为什么React中使用useState后,Chrome的Blink引擎没有立即更新DOM?

开发者逸轩 阅读 50

我写了一个简单的计数器组件,点击按钮时用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需要强制同步刷新?或者我的依赖项漏了什么?

我来解答 赞 5 收藏
二维码
手机扫码查看
2 条解答
欧阳书圻
这不是 Blink 引擎的问题,也不是 DOM 更新延迟。你看到的现象是完全正常的 React 行为,根本原因在于 setCount 是异步的,而你在 onClick 里打印的是闭包中的旧 count 值。

你这里的 console.log('Clicked:', count) 拿到的是点击瞬间组件当前渲染周期里的 count,即使你调用了 setCount,这个 count 也不会立刻更新,因为 state 更新会触发重新渲染,但当前执行上下文中的变量不会变。

真正要做校验的是:不要在更新 state 后立即依赖它的值。你应该在 useEffect 里监听 count 变化,而不是在事件回调里读取当前的 count

function Counter() {
const [count, setCount] = useState(0);

useEffect(() => {
console.log('Count updated to:', count);
}, [count]);

return (

Current: {count}




);
}


React 在所有浏览器里都是一样的调度机制,Chrome 的 Blink 和其他内核没有差异。你看到的“慢半拍”其实是预期行为——state 更新不是同步提交的,尤其是当你在事件处理函数里连续多次调用 setCount,React 还会合并更新。

如果你想在调试时看到最新的值,可以这样:

setCount(prev => {
const next = prev + 1;
console.log('Now setting count to:', next); // 这里能看到新值
return next;
});


总之,这不是渲染问题,也不是浏览器 bug,是 React 的 state 异步更新模型导致的。别被 console.log 迷惑了,页面最终显示是对的就行。要做校验的话,应该通过 useEffect 监听状态变化,而不是在事件中读取当前 state。
点赞 8
2026-02-10 18:18
UI婧妍
UI婧妍 Lv1
你这是闭包导致的count值没及时更新,React的state更新是异步的,console.log里拿不到最新的值。用useRef保存count值就能拿到最新值:

function Counter() {
const [count, setCount] = useState(0);
const countRef = useRef(count);

useEffect(() => {
countRef.current = count;
}, [count]);

return (
<div>
<p>Current: {count}</p>
<button onClick={() => {
setCount(prev => prev + 1);
console.log('Clicked:', countRef.current); // 这里能拿到最新值
}}>
Add
</button>
</div>
);
}
点赞 10
2026-02-05 08:17