react查询结果对象由于闭包而过时吗?



我一直觉得我对JS闭包是如何工作的有一个相当坚实的理解,但是自从过去几个月使用ReactJS以来,有些东西我不能完全理解。

在下面的示例中,查询结果对象getData如果在其他查询的成功回调中使用,是否会过期?

我的闭包本能告诉我是,但我的反应本能告诉我不,出于某种原因,我不明白为什么它是这样工作的。

感谢所有的帮助!

/*
* Custom query hooks
*/
function useGetData(someId, opts){
return useQuery(['getData', someId], 
getDataQueryFn,
{
...opts,
},
);
}
function useOtherData(someId, opts){
return useQuery(['otherData', someId], 
otherDataQueryFn,
{
...opts,
},
);
}
/*
* React component
*/
function MyComponent(){
const getData = useGetData("1");
const otherData = useOtherData("1", {
onSuccess: () => {
// QUESTION: if I use getData here, won't it be stale due to closure? why or why not?
}
});
// render and stuff...
}

不会过时。这是一个codesandbox,它在计数器上关闭,取回需要5秒才能完成。来自沙箱的相关代码:

const [count, inc] = React.useReducer((val) => val + 1, 0);
const { data } = useQuery(
"repoData",
async () => {
await waitFor(5000);
return Promise.resolve({ name: "foo " });
},
{
onSuccess: () => console.log(count)
}
);

如果在前5秒内单击计数器几次,则仍将记录最新的计数。不管你是在本地状态上闭包还是在其他查询上闭包都没有关系。

原因很可能是react-query只会在 Promise成功后触发重新呈现(这是一个简单的通过useState在底层强制重新呈现),并且在那个时候,react已经"看到"了。最近的值,而不是查询开始取值时的值。

这取决于useQuery的实现。然而,我很确定它不会使用陈旧的数据。我希望以下顺序:

  • 每次useGetData的结果更新-重新渲染发生,由于一些内部状态更新
  • >onSuccess回调(在闭包中捕获最新的getData结果)通过props传递给useOtherData并由库拾取以处理下一次更新

最新更新