英文:
How do a fetch race condition flag in React's useEffect hook between different calls?
问题
这个问题可能是一个简单的问题,但我在我的搜索中没有找到任何东西。不同的useEffect钩子调用如何共享在fetch竞争条件标志中的值?
我的意思是,在这个链接中:使用useEffect钩子获取数据的竞争条件,作者使用一个名为active的标志来控制获取数据的竞争条件。我想知道useEffect钩子的前一个(或下一个)调用如何访问来自清理函数的返回值false(这个值是如何共享的?),以及它是如何在JavaScript调用堆栈中工作的。
英文:
This question might be a simple question, but I found nothing in here in my searches. How do different useEffect hook calls share the value in a fetch race condition flag?
What I meant is that, in this link: race condintions in fetching data with useEffect hook, the author uses a flag active to control race condition on fetches. I want to know how the previous (or next) call of the useEffect hook gets access to the returned value false from the clean up function (how is the value shared?). And how does it work in the javascript callstack.
答案1
得分: 0
上一个(或下一个)useEffect钩子的调用如何访问清理函数返回的值?这个值是如何共享的?
根本不共享。每个effect执行都有自己的active值 - 它只在异步的fetchData函数和返回的清理函数之间共享,它们都是在相同作用域下的闭包。
只是React在运行组件状态改变时,会在再次运行effect之前清理上一次渲染的effect。它会记住返回的清理函数(如果有的话),只要effect还在运行,就会在effect结束时调用它。
英文:
> How does the previous (or next) call of the useEffect hook get access to the returned value from the clean up function? How is the value shared?
It is not shared at all. Every effect execution has its own active value - it is only shared between the asynchronous fetchData function and the returned cleanup function, they are both closures over the same scope.
It's just that react cleans up the effect from the last render before running the effect again when the component state changes. It remembers the returned cleanup function (if any) while the effect is active, and calls it when the effect should end.
答案2
得分: 0
我也对这篇帖子感到非常困惑。作用域方面没有什么神奇的事情,每个清理函数只能访问其作用域内定义的 active 实例。关键细节在于,尽管 useEffect 函数调用会进行长时间的 API 请求,但函数本身几乎立即返回一个待处理的承诺(promise)。因此,当你第二次点击获取按钮时,第一个请求的清理函数会立即运行,并将请求1的 active 设置为 false。
使用提供的 CodeSandbox 的示例时间线:
- 点击获取按钮1。
useEffect函数运行:active1 = true,APIrequest1发送。- 待处理 的
request1承诺立即返回。request1尚未 完成。 - 点击获取按钮2。
- 在再次运行
useEffect函数之前,按钮1的清理函数运行(即使request1尚未完成!):active1 = false。 useEffect函数再次运行:active2 = true,APIrequest2发送。request1最终完成,但其结果被忽略,因为在步骤5中将active1设置为了 false。request2最终完成,其结果被使用,因为active2仍然为 true。
使用 CodeSandbox 的分支版本,其中添加了 console.log 帮助我搞清楚情况。
英文:
I was very confused by this post as well. There's nothing magical going on with scopes, each clean up function only has access to the instance of active defined within its scope. The key detail is that although the useEffect function call has a long running API request, the function itself returns almost immediately with a pending promise. Therefore, when you click the fetch button a second time, the clean up function for the first request runs immediately, and set request 1's active to false.
Example timeline using the provided CodeSandbox:
- Fetch button press 1.
- useEffect function runs:
active1 = true, APIrequest1sent. - Pending promise for
request1returned immediately.request1has not completed. - Fetch button press 2.
- Before useEffect function runs again, button press 1 clean up runs (even though
request1hasn't finished yet!):active1 = false. - useEffect function runs again:
active2 = true, APIrequest2sent. request1finally completes, but its results are ignored becauseactive1was set to false in step 5.request2finally completes, and its results are used, because itactive2is still true.
Forked CodeSandbox with added console.log's that helped me sort it out.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论