useCallback状态不更新的解决方法

4,707 阅读2分钟

状态不更新的原因

在使用useCallback的时候,偶尔会遇到deps已经更新了,但是调用执行useCallback定义的函数时,内部的deps状态还是旧的。大部分情况是因为调用的useCallback函数是旧的,而不是deps更新后新生成的useCallback;

下面是一个示例:

点击按钮,useCallback执行打印的值永远是初始值0。这是因为没有将getLatestCount加入到onClick的deps中,导致每次执行onClick,执行的getLatestCount都是初始的函数,因此获取到的count总是0;

解决方法

将useCallback函数加入deps

如下图所示意,将getLatestCount加入onClick的依赖中,这样每次执行onClick的时候,用的都是最新的getLatestCount函数,打印的count是最新的值

这里有一点要注意,一旦我们使用了useCallback,并且每次都要获取deps最新的状态的话。我们就需要在所有调用useCallback函数的地方,将定义的useCallback加入依赖中,这样才能保证每次useCallback函数拿到的deps的值都是最新的值。

使用useRef保存状态的引用

我们可以将useCallback函数中使用的状态数据包裹在useRef中,保留其引用。这样不论状态如何改变,总能通过useRef的引用获取到最新的状态。

代码如下:

结语

useCallback将函数包裹起来,可以达到当依赖的deps不改变的情况下,返回的函数引用依然不变,避免重新构造一次函数。但是若要保持每次使用的useCallback中的状态是最新的,那么就需要在使用useCallback的地方,将useCallback加入到deps中。

所以,笔者建议,若是没有非常大的性能消耗的话,尽量不要使用useCallback,而是直接定义裸的函数,如下图所示:

相关资料

  1. React useCallback源码:github.com/facebook/re…