react hooks 中 setState 的疑惑?

小夜勃
  • 221

学习 react hooks 的时候遇到了一点疑惑, 如下:

setState 貌似是可以有两种写法, 似乎产生了不同的效果

const Counter = props => {
  const [count, setCount] = useState(0)

  const addTwice1 = () => {
    setCount(prevCount => prevCount+1)
    setCount(prevCount => prevCount+1)
  }

  const addTwice2 = () => {
    setCount(count+1)
    setCount(count+1)
  }
  
  return (
  // ....
  )
}

上面的代码中, 如果执行第一个addTwice1, 似乎 count 是可以一次性加 2 的, 但是如果调用 addTwice2, 似乎每次还是只能加 1. 想请教一下对于第二种, 是不是和 class 组件里的setState类似, 状态是无法合并更新的, 而第一种类似setState里传入了一个回调函数, 可以合并更新? 请问这两种写法的区别在哪, 以及是否有相关文章可以参考? 感谢

回复
阅读 4.9k
2 个回答
✓ 已被采纳

第二个count + 1由于闭包的关系, 实际上第二次执行的count + 1里的count依然是1 , 也就是执行了两次 setCount(2)

addTwice2调用后结果是1应该很好理解,setCount是异步执行,第一个setCount执行时count是0所以执行的是setCount(1),由于异步此时继续执行第二个setCount,此时count还是0,因为第一个setCount是异步所以count还未更新,所以此时第二个执行的也是setCount(1),所以最终的count是1;addTwice1中setCount参数是函数,我们打印下函数的执行过程:

        setCount(prevCount => {
            console.log('执行函数1')
            return prevCount+1
        })
        setCount(prevCount => {
            console.log('执行函数2')
            return prevCount+1
        })
        console.log('赋值完毕')

结果是执行函数1、赋值完毕、执行函数2,所以我是这样理解这个过程的,执行到第一个setCount代码,此时发现异步队列中没有其它的更新函数,也就是第一个setCount处于队列顶部,那么对于函数参数直接调用获取返回值,后面的更新函数都是在上一下更新函数执行完毕,所以真正的给React内部state赋值时才去执行函数参数,所以第二个setCount获取的是第一个setCount更新后的count,也就是1,所以实际上执行的是setCount(2),因此最终count是2.~~~~

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏