React 查询结果对象会因为关闭而过时吗?

Do react query result objects go stale due to closures?

我一直觉得我对 JS 闭包的工作原理有相当扎实的理解,但是自从最近几个月使用 ReactJS 以来,有些事情我不太明白。

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

我的关闭直觉告诉我是的,但出于某种原因我的 reactjs 直觉告诉我不是,我无法理解为什么它会这样工作。

感谢所有帮助!

/*
* 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...
}

这取决于 useQuery 实施。但是我很确定它不会使用过时的数据。我期待以下顺序:

  • 每次更新 useGetData 的结果 - 由于某些内部状态更新,都会发生重新渲染
  • new onSuccess 回调(在关闭时捕获最新的 getData 结果)通过 props 传递给 useOtherData 并由处理下一次更新的库

它不会过时。 Here's 一个在计数器上关闭的代码和框,提取需要 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 已经“看到”了最新的值,而不是查询开始获取时的值。