跳转至

2026-05-26 学习日志

今日主题

  • React Router setSearchParams 的闭包陷阱

新增认知

React Router setSearchParams 的闭包陷阱

  • setSearchParams 的 functional updater 在连续调用时失效
    React Router v7 的 setSearchParams 内部用 useCallback 捕获 searchParams(来自 useMemo 依赖 location.search),
    而 location 是 React state,在同一事件处理内不会更新。
    因此连续两次 setSearchParams(prev => ...) 收到的 prev 是同一份过时值,后一次调用会覆盖前一次。
    history.replaceState 虽同步更新 window.location,
    但 React Router 的 location state 需等重渲染后才刷新,导致 functional updater 形同虚设。

  • URL 参数的 ground truth 是 window.location.search
    当同一事件处理中需多次修改 URL search params 且后次需感知前次变更时,
    必须直接从 window.location.search 读取而非依赖 React Router 的 searchParams state。
    因为 history.replaceState 同步更新 window.location,而 React Router 的派生 state 不会。
    基于 window.location 构建新的 URLSearchParams 再传给 setSearchParams,
    每个调用都能看到前面调用对 URL 的修改,从根本上避免覆盖。