
useUrlState 是我封装的 hooks ,返回 state 和 stateSetter
另外如果在多个组件中使用同一个 key( useUrlState 的第一个参数),那么组件之间就可以共享 setter 和 state
以下是 API 调用的形式:
const [searchWord, searchWordSet] = useUrlState("searchWord", ""); const [filterStatus, filterStatusSet] = useUrlState("filterStatus", ""); <input value={searchWord} OnChange={e=>searchWordSet(e.target.value)}/> 在 react-router v6 基础山,封装了一下 useSearchParams :
import { useCallback, useEffect } from "react"; import { useSearchParams, NavigateOptions } from "react-router-dom"; export const navigateOptions: NavigateOptiOns= { replace: true, }; const useUrlState = (key: string, state: string) => { const [searchParams, setSearchParams] = useSearchParams(); useEffect(() => { const hasStateInUrl = searchParams.has(key); const urlState = searchParams.get(key) || ""; if (!hasStateInUrl && urlState !== state) { searchParams.set(key, state); setSearchParams(searchParams, navigateOptions); } }, [searchParams, state, key]); const setter = useCallback( (newState: string) => { searchParams.set(key, newState); setSearchParams(searchParams, navigateOptions); }, [key, searchParams] ); return [searchParams.get(key) || state, setter] as const; }; export default useUrlState; 正常情况下使用表现良好,但是如果出现连续的 setter ,例如
const [pageSize,pageSizeSet]=useUrlstate("pageSize","10"); const [pageIndex,pageIndexSet]=useUrlstate("pageIndex","1"); //下面是连续调用 setter onPagingChange({ pageIndex, pageSize }) { pageSizeSet(pageSize); pageIndexSet(pageIndex) } 连续的 setter 的第一个不会生效,例如的代码 pageSizeSet 就不会生效。
原因是因为两个 setter 执行起点是一样的,最后只有后面那个覆盖前面的
我尝试 setSearchParams 接受变更函数来更改 url ,结果依旧会产生覆盖的 bug 。
求解决思路
1 XCFOX 2022-11-18 20:25:08 +08:00 每个 useSearchParams 都是独立的,需要自己通过状态管理去通信 https://codesandbox.io/s/silly-pike-vlmo5v?file=/src/useUrlState.tsx:229-582 相关 issue: https://github.com/remix-run/react-router/issues/8587 https://github.com/remix-run/react-router/issues/9290 |