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 1
每个 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 |