How useEffect memorize states
/ 4 min read
直接上最终的代码:
foo
的函数参数当第一次被执行, 就会被锁住, 不论以后执行多少次, 也不会变化.
当第一次执行 bar
时候, bar
函数所创建的环境会被 foo
参数闭包捕获, 里面用到的 a 和 b, 是第一次执行生成的 a 和 b.
当执行到 setA(2) setB(3)
时候, memorizedVal
和 bar
环境下的 b 被修改了. 注意这里修改的不是 a
, 而是 memorizedVal
,想要获取最新的 a 需要下一次执行 bar()
, 所以此时 log 会打印 0(a) 和 3(b).
当执行到第二遍 bar()
时, 由于 foo
里面锁住, 传入的参数可以忽略, 其还是执行第一次的 callback, 所以数据还是取自第一次闭包环境. 第一次闭包环境下 a=0
, 而 b 已经被下面的 setB(3)
修改成 3.
所以会有结果: 0 3 0 3
.
例子1
在3秒内, 点击按钮5次, 它会 log: 0 1 2 3 4 5
, 因为 useEffect
没有 deps
默认 update 后重新执行.
例子2
例子1中如果改成 class component 则最终结果是 0 5 5 5 5 5
.
例子3
例子4
这里会 log: 0 5 5 5 5 5
.
例子5
例子6
例子
这里为什么要用 ref 来存储 selector
?
因为下面的 useEffect
里面要使用, 如果不用 ref+useEffect
来更新而直接使用 selector, 则该监听器会捕获组件挂载时的 selector,而不会随后续 selector 的更新而更新, 每次传入的函数都是变化的, 而 useRef 不会导致组件重新渲染,这有助于提高性能。