React的setInterval的闭包陷阱React的闭包陷阱在有些地方比较隐蔽,今天在工作中遇到了这个问题 在onC
React的闭包陷阱在有些地方比较隐蔽,今天在工作中遇到了这个问题 在onClick中触发一个setInterval,发现里面打印的值永远都是最初设定的值,但是外面的值却是新的。
export default () => {
const [count, setCount] = useState(0)
console.log('[ outer ]', count)
const countLog = () => {
console.log('[inner]', count)
setCount(c => c + 1)
}
return (
<div>
<button onClick={() => {
setInterval(countLog, 1000)
}}>log</button>
<div>{count}</div>
</div>
)
}
刚开始有点疑惑,既然外面的值是新的,为什么里面的会是旧的,我理解查找的作用域链是这样的
也就是每次重渲的时候,触发的都是新的setInterval回调,此时找到最新的外部count值。
实际上不是的,setInterval的回调函数保存的是我们第一次的那个函数,虽然我们每次重渲的时候countLog更新了,但我们setInterval里引用的还是第一次那个函数(假如会更新才奇怪)。每次渲染相当于有一个副本。而setInterval的回调函数只有第一次触发,所以一直引用的是第一个副本。 因此就变成了这种形式
这也解释了为什么外部渲染的值是新的,而setInterval的回调里的值永远是旧的。
解决办法倒是很简单,可以用函数setState在里面拿到最新的值。
setCount(c=>{
// c是最新的值
})
这个例子又加深了对react闭包的理解😂
转载自:https://juejin.cn/post/7400958526155784218