我想知道React如何在使用useCallback
钩子(以及其他钩子)时“冻结”闭包,然后在将钩子内使用的变量传递给inputs
参数时只更新它们。
我明白“冻结”可能不是很清楚,所以我创建了一个REPL.it来说明我的意思:https://repl.it/repls/RudeMintcreamShoutcast。打开代码后,打开Web浏览器控制台,开始单击count
按钮。
为什么外部的值和内部的值是不同的,对于同一个变量,如果它们在相同的闭包下,引用相同的东西?我不熟悉React代码库,所以我想我在这里遗漏了一个底层实现细节,但是我试着思考了几分钟,但是不能很好地理解React是如何实现的。
2条答案
按热度按时间n9vozmp41#
第一次呈现组件时,
useCallback
钩子会把传递过来的函数作为它的参数,并把它存储在后台。当你调用回调时,它会调用你的函数。到目前为止,一切都很好。第二次呈现组件时,
useCallback
钩子将检查您传入的依赖项。如果它们没有改变,* 您传入的函数将被完全忽略 *!当您调用回调时,它将调用您在第一次呈现时传入的函数,这与作为依赖项传入的值无关--这只是普通的JavaScript闭包!当依赖关系发生变化时,
useCallback
钩子会接受你传入的函数,并替换它已经存储的函数。当你调用回调函数时,它会调用 * 新 * 版本的函数。因此,换句话说,没有“冻结”/条件更新的变量-它只是存储一个函数,然后重新使用它,没有比这更花哨的了:)
**EDIT:**下面的例子演示了纯JavaScript中的情况:
hvvq6cgz2#
我来到这里,也带着一个类似的、相当模糊的不确定性,即关于
useCallback
的工作方式,以及它与闭包的交互作用(我也直观地理解你的措辞,关于useCallback
应该如何“冻结”闭包),但我对公认的答案感到相当困惑,它似乎与(我所理解的)你的问题并不完全一致。对我来说,理解发生了什么的方法是看两个非常简单的闭包(都在定义了单个状态变量
a
的同一个环境中),有和没有useCallback
,看看会发生什么。在使用Reactlinter的情况下,必须忽略它的警告(将a
作为依赖项包括在内),以便真正说明差异:所以我们清楚地看到
useCallback
在某个时刻有效地“冻结”了它的闭包,这是一个必须清楚理解的概念,以避免混淆问题。本文可能比我更好地解释了它:https://tkdodo.eu/blog/hooks-dependencies-and-stale-closures