为啥清理 useEffect 挂钩将 RTKQ 的结果视为 isLoading 以及如何避免该问题?
Posted
技术标签:
【中文标题】为啥清理 useEffect 挂钩将 RTKQ 的结果视为 isLoading 以及如何避免该问题?【英文标题】:Why is the cleanup of an useEffect hook seeing the result of an RTKQ as isLoading and how to avoid the issue?为什么清理 useEffect 挂钩将 RTKQ 的结果视为 isLoading 以及如何避免该问题? 【发布时间】:2021-10-11 19:27:40 【问题描述】:我有一个 React 函数组件(一个路由组件),它在卸载时应该做一些事情(即用户单击浏览器的后退按钮)并包含以下相关行:
// ...
const params = useParams<ISomeInterfaceHere>();
// ...
// I verified that `data` below actually loads but it does not last until the component unmounts.
const data, isLoading, isError = useGetSomethingQuery(params.x,
refetchOnMountOrArgChange: true,
);
// ...
useEffect(() =>
return () =>
// current state:
//
// isLoading === true
// isError === false
// data === undefined
;
, []);
// ...
它是否与来自react-router
包的useParams
挂钩有关?这是 RTKQ 中的错误,或者,如果不是,定义的行为是什么?而且,最重要的是,我如何才能在组件卸载之前获得最后定义的 data
值?
没有错误消息。
更新 1
我用:
"react": "^16.14.0",
"react-router": "^5.1.2",
"react-router-dom": "^5.1.2",
"@reduxjs/toolkit": "^1.6.0",
更新 2
我确信params
没有更新,甚至params.x
也没有。我也升级到了@reduxjs/toolkit
v1.6.1
,我也遇到了同样的问题。
更新 3
具有独立问题的代码沙箱是 here。在我看来这是 RTKQ 中的一个错误。
更新 4
我打开了一个 GH 错误报告 here。
【问题讨论】:
refetchOnMountOrArgChange
。只是通过它的名称,看起来数据将被再次获取,以防任何参数被更改。您确定参数没有更新吗?
@kumarmo2 是的,我确定。
【参考方案1】:
您正在第一次渲染时创建清理回调。从那一刻起,该回调将保留从第一次渲染到执行的陈旧变量,即使中间发生了数百次渲染。
这与 RTKQ 无关——这只是 React 的工作原理。如果您想访问该清理中的最新值,则必须通过 ref 对其进行隧道传输:
const data, isLoading, isError = useGetSomethingQuery(params.x,
refetchOnMountOrArgChange: true,
);
const ref = useRef(data, isLoading, isError)
useEffect(() => ref.current = data, isLoading, isError , [data, isLoading, isError])
// ...
useEffect(() =>
return () =>
console.log(ref.current)
;
, []);
【讨论】:
以上是关于为啥清理 useEffect 挂钩将 RTKQ 的结果视为 isLoading 以及如何避免该问题?的主要内容,如果未能解决你的问题,请参考以下文章
为啥我的组件在使用 React 的 Context API 和 useEffect 挂钩时会渲染两次?
在 useEffect 挂钩中使用 axios 取消令牌时如何修复失败的测试