反应查询结果对象是不是由于关闭而过时?

Posted

技术标签:

【中文标题】反应查询结果对象是不是由于关闭而过时?【英文标题】:Do react query result objects go stale due to closures?反应查询结果对象是否由于关闭而过时? 【发布时间】:2021-10-31 01:55:35 【问题描述】:

我一直觉得我对 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...

【问题讨论】:

【参考方案1】:

它不会过时。 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 已经“看到”了最新的值,而不是查询开始获取时的值。

【讨论】:

【参考方案2】:

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

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

【讨论】:

以上是关于反应查询结果对象是不是由于关闭而过时?的主要内容,如果未能解决你的问题,请参考以下文章

如何从原始查询中检索结果集作为数组而不是 Laravel 3 中的对象

休眠条件查询返回过时的结果

简单的代码,看似随机的结果 - 这是由于过时的引用吗?

SQLAlchemy 获取类对象而不是实际结果

设计模式之模板模式

MySQL查询返回资源ID#8,而不是所需值[关闭]