为啥清理 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/toolkitv1.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` 的清理功能?

在 useEffect 挂钩中使用 axios 取消令牌时如何修复失败的测试

如何将 setState 值插入 useEffect 挂钩?

如何将参数传递给 useEffect 挂钩

反应:仅将主体类添加到 useEffect 挂钩中的某些组件?