React中setState执行逻辑疑问:连续调用为何未按预期更新?
嘿,我完全理解你作为React新手遇到这个问题的困惑——我刚学React的时候也踩过一模一样的坑!让我们一步步拆解你遇到的问题:
首先,核心原因是React的setState是异步且会批量处理更新的,尤其是在像onClick这种React合成事件里。当你连续调用两次setState时,React不会立刻更新state,而是会把这些更新请求暂时攒起来,最后一次性合并处理。
看你的代码:
handleReset() { this.setState({count:0}) this.setState({count:this.state.count+1}) }
你原本预期会先把count设为0,再加1得到1,但实际上,两次setState调用时,this.state.count都还是初始的5——因为state还没来得及更新!所以第二次setState相当于count:5+1=6。最后React合并这两个更新,后面的更新会覆盖前面的,所以最终state就变成了6。
那怎么得到你想要的结果呢?用函数式的setState就可以完美解决!函数式的setState会接收上一次更新后的state(也就是prevState)作为参数,这样就能保证每次更新都基于最新的state值:
handleReset() { this.setState(prevState => ({ count: 0 })); this.setState(prevState => ({ count: prevState.count + 1 })); }
这次,第一个setState把prevState.count改成0,第二个setState拿到的prevState就是更新后的0,加1后就得到1,最终结果就完全符合你的预期啦!
额外补充一点:不是所有场景下setState都是异步的。比如在setTimeout、原生DOM事件或者Promise回调里,React不会批量处理更新,setState会同步生效。不过大多数日常开发场景里,我们遇到的都是合成事件里的批量异步更新,所以记住函数式setState的用法很实用。
内容的提问来源于stack exchange,提问作者Dickens

