React Query返回的结果对象是否会因闭包导致数据过时?
结论
你给出的示例代码中不会出现闭包导致的getData过时问题,具体原因如下:
运行逻辑说明
- React组件每次触发重渲染时,
MyComponent函数会完整执行一次:- 每次执行都会调用
useGetData("1")拿到当前最新的查询结果对象getData - 每次执行都会重新生成一个全新的
onSuccess回调函数,这个新回调的闭包捕获的就是本次渲染的最新getData变量
- 每次执行都会调用
- React Query的
useQuery内部会自动同步更新你传入的配置项(包括onSuccess回调),当otherData查询成功触发回调时,调用的永远是最近一次渲染传入的最新版本回调,自然拿到的就是最新的getData。
唯一会出现过时的例外场景
只有当你对传入useOtherData的配置项做了静态化处理,且没有把getData加入依赖数组时,才会出现闭包过时问题,示例如下:
function MyComponent(){ const getData = useGetData("1"); // 错误示例:useMemo依赖数组为空,onSuccess永远是第一次渲染生成的版本 const otherDataOpts = useMemo(() => ({ onSuccess: () => { console.log(getData) // 这里拿到的永远是第一次渲染的getData,会过时 } }), []) const otherData = useOtherData("1", otherDataOpts); }
兜底优化方案
如果想要彻底规避闭包相关的隐患,可以直接从React Query的全局缓存中拉取最新数据,不需要依赖闭包捕获的变量:
import { useQueryClient } from '@tanstack/react-query' function MyComponent(){ const queryClient = useQueryClient() const otherData = useOtherData("1", { onSuccess: () => { // 直接从缓存拿最新数据,完全绕开闭包问题 const latestGetData = queryClient.getQueryData(['getData', '1']) } }); }
内容的提问来源于stack exchange,提问作者pooley1994
相关产品推荐
相关产品推荐

