为什么React中使用useState后,Chrome的Blink引擎没有立即更新DOM?
我写了一个简单的计数器组件,点击按钮时用useState更新count,但发现Chrome里DOM的显示总比state慢半拍。比如第一次点击后,控制台打印count是1,但页面还是显示0,再点第二次才显示1。其他浏览器没问题,这是Blink的渲染机制导致的吗?
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>Current: {count}</p>
<button onClick={() => {
setCount(prev => prev + 1);
console.log('Clicked:', count); // 第一次点击这里还是0
}}>
Add
</button>
</div>
);
}
我试过把setCount改成函数式更新,但问题依旧。难道Blink需要强制同步刷新?或者我的依赖项漏了什么?
setCount是异步的,而你在onClick里打印的是闭包中的旧count值。你这里的
console.log('Clicked:', count)拿到的是点击瞬间组件当前渲染周期里的count,即使你调用了setCount,这个count也不会立刻更新,因为 state 更新会触发重新渲染,但当前执行上下文中的变量不会变。真正要做校验的是:不要在更新 state 后立即依赖它的值。你应该在
useEffect里监听count变化,而不是在事件回调里读取当前的count。React 在所有浏览器里都是一样的调度机制,Chrome 的 Blink 和其他内核没有差异。你看到的“慢半拍”其实是预期行为——state 更新不是同步提交的,尤其是当你在事件处理函数里连续多次调用
setCount,React 还会合并更新。如果你想在调试时看到最新的值,可以这样:
总之,这不是渲染问题,也不是浏览器 bug,是 React 的 state 异步更新模型导致的。别被 console.log 迷惑了,页面最终显示是对的就行。要做校验的话,应该通过
useEffect监听状态变化,而不是在事件中读取当前 state。