likes
comments
collection
share

React的setInterval的闭包陷阱React的闭包陷阱在有些地方比较隐蔽,今天在工作中遇到了这个问题 在onC

作者站长头像
站长
· 阅读数 21

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>
  )
}

React的setInterval的闭包陷阱React的闭包陷阱在有些地方比较隐蔽,今天在工作中遇到了这个问题 在onC

刚开始有点疑惑,既然外面的值是新的,为什么里面的会是旧的,我理解查找的作用域链是这样的

React的setInterval的闭包陷阱React的闭包陷阱在有些地方比较隐蔽,今天在工作中遇到了这个问题 在onC

也就是每次重渲的时候,触发的都是新的setInterval回调,此时找到最新的外部count值。

实际上不是的,setInterval的回调函数保存的是我们第一次的那个函数,虽然我们每次重渲的时候countLog更新了,但我们setInterval里引用的还是第一次那个函数(假如会更新才奇怪)。每次渲染相当于有一个副本。而setInterval的回调函数只有第一次触发,所以一直引用的是第一个副本。 因此就变成了这种形式

React的setInterval的闭包陷阱React的闭包陷阱在有些地方比较隐蔽,今天在工作中遇到了这个问题 在onC

这也解释了为什么外部渲染的值是新的,而setInterval的回调里的值永远是旧的。

解决办法倒是很简单,可以用函数setState在里面拿到最新的值。

setCount(c=>{
// c是最新的值
})

这个例子又加深了对react闭包的理解😂

转载自:https://juejin.cn/post/7400958526155784218
评论
请登录