我有一个名为useFetch的自定义钩子:
const useFetch = (url: string, method = 'get', queryParams: any) => {
useEffect(() => {
let queryString = url;
if (queryParams) {
queryString += '?' + queryParams;
}
// omitted try and catch construction for code readability
const result = await fetch(queryString, method, queryParams);
return await result.json();
}, [url, method, queryParams]);
}
使用useFetch
的组件:
const { response, error } = useFetch(
'/orders',
'get',
new URLSearchParams({
limit: state.limit.toString(),
offset: state.offset!.toString()
}).toString()
);
如果我将queryParams
作为字符串传递,则不会得到无限的重新渲染循环,因为它是原始类型String
,但是如果我使用:
const { response, error } = useFetch(
'/orders',
'get',
{
limit: state.limit.toString(),
offset: state.offset!.toString()
}
);
然后分别更改useEffect
:
let queryString = url;
if (queryParams) {
queryString += '?' + new URLSearchParams(queryParams).toString();
}
即使queryParams
不会发生很大变化,这也会导致重新呈现,因为{} !== {}
,我可以这样做:
const queryParamsRef = useRef(queryParams);
那我就不会重新渲染,因为在每次重新渲染时,它都是通过引用引用的相同对象,但是正如您所注意到的,我在此queryParams
对象中使用状态变量,因此当状态为进行更改,因为queryParamsRef
仍引用先前的对象,所以我不会重新渲染。
解决此问题的最佳方法是什么?是否可以像我的第一个代码块一样将其作为字符串传递?
答案 0 :(得分:0)
如果可能的话,最好的办法是不使用url的参数来获取值,但是如果需要,我个人将https://github.com/sindresorhus/query-string与“ window.location.search”一起使用。