乐观 URL 状态
真实应用中,URL 更新不只是 setSearchParams。
用户可能连续输入、切换筛选器、点击分页。Decurl 在 React Router 集成层提供 optimistic search state:
- 用户调用 setter。
- Decurl 立即更新本地 snapshot,让 UI 先响应。
- 多次 patch 会被合并或重放。
- 到达 flush 时机后,再调用 React Router navigate。
- React Router 确认 location 后,store 与实际 URL 对齐。
为什么需要 optimistic
没有 optimistic 时,UI 很容易被 router 更新节奏限制。尤其是输入框或复杂筛选器,用户期望界面立即反应。
Decurl 的 setter 会先把 patch 应用到本地 search snapshot:
组件读取到的 values 会立刻变化,不需要等待浏览器地址栏完成更新。
Patch 重放
当多个更新连续发生时,Decurl 会按顺序重放 patch。
每一次 setSearchValue 或 setSearchValues 调用,都会在本地 store 中形成一个待处理的 update entry。entry 记录这次更新的 patch 和 navigate options;在 flush 之前,这些 entry 会先作用在本地 search snapshot 上,让组件立即读到新值。
重放时,Decurl 会按 entry 创建顺序依次应用 patch。第二个 updater 会基于第一个 patch 后的中间值计算,而不是基于旧 URL。
这对分页、筛选器联动和批量更新很重要。
Flush 策略
需要配置 flush 策略时,可以在 SearchProvider 上设置 store options。
常见策略:
外部 location 变化
浏览器 back/forward 或其他组件触发 navigation 时,React Router 的 location 可能从外部改变。
Decurl 会把外部 location 视为新的事实来源,并丢弃不再适用的 pending patch。
这保证了 URL 的最终语义仍然由 router location 决定,而不是由本地 store 单方面决定。
与其他 search params 管理方式共存
Decurl 可以和其他基于 React Router 的 search params 管理方式共存,例如 React Router 自带的 useSearchParams。
Decurl 把 React Router 的 location 作为唯一可信输入。只要其他工具也是通过 React Router 更新 URL,Decurl 就会在 location 变化后重新读取当前 URL,并按 Search Fields 重新 decode。
这个特性对已有项目的渐进迁移比较友好。你可以先让新页面或部分字段使用 Decurl,其他历史代码继续使用原有的 search params 管理方式。如果 flushDelay 较短,Decurl 的 pending entry 通常会很快写入 URL,和其他管理器发生竞争的时间窗口也会比较小。
需要注意的是,Decurl 不会理解其他 search params 管理器内部的状态。如果 Decurl 还有尚未 flush 到 URL 的 pending entry,而另一个管理器先更新了 React Router location,Decurl 会以新的 location 为准,并清理这些尚未提交的 entry。
因此,迁移期可以让不同工具共存;但在同一个页面里,仍然建议让同一组 search params 由一种方式负责,避免多个管理器同时更新同一个 key。
这个行为保证了 URL 始终是最终状态来源:一旦 React Router location 被确认,Decurl 会放弃本地尚未提交的中间状态。
默认 navigate 行为
Search state 更新默认使用 { replace: true },因为输入和筛选器变化通常不应该制造大量 history entry。
如果某次更新需要创建新的 history entry,可以在 setter 的第二个参数中覆盖默认值:
其他选项及默认值见 Navigate options。