You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中useEffect存在时useState更新回调与同步代码执行顺序异常咨询

执行顺序差异的核心原因

这个现象是React 17及更早版本的Legacy渲染模式下,批量更新机制的特殊实现逻辑导致的:

无useEffect时的执行逻辑

当你注释掉空依赖useEffect后,组件首次渲染完成后没有待处理的更新任务,默认上下文下批量更新开关isBatchingUpdates值为false。
你点击按钮触发回调后:

  • 先执行onChange内的setState1,因为批量更新未开启,React会同步执行你传入的状态更新函数,直接打印onChange set state完成状态更新
  • 再执行onChange2,打印onChange2
    所以最终日志顺序是onChange set state在前,onChange2在后。

有useEffect时的执行逻辑

当你保留useEffect时,组件首次挂载完成后会触发useEffect执行,内部的setState会触发一次组件重渲染:
React处理useEffect内的更新时,会临时开启批量更新,本次重渲染完成后,isBatchingUpdates开关的重置逻辑存在延迟,导致后续第一次用户触发的事件回调执行时,批量更新开关依然处于开启状态。
此时你点击按钮触发回调后:

  • 先执行onChange内的setState1,因为批量更新已开启,React不会同步执行更新函数,而是先把更新推入待处理队列,继续执行后续同步代码
  • 再执行onChange2,打印onChange2
  • 等整个onClick回调执行完成后,React才会批量处理队列中的更新,执行setState1的更新函数,打印onChange set state
    所以最终日志顺序是onChange2在前,onChange set state在后。

补充说明

该差异仅存在于React 17及更早的Legacy模式中,React 18默认开启自动批量更新,不管是否有该useEffect,点击按钮的日志都会是onChange2在前,更新函数日志在后。

内容的提问来源于stack exchange,提问作者Dmitriy Glazkov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 05:24:07