react18-batching-patterns

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

React 18 Automatic Batching Patterns

React 18 自动批处理模式

Reference for diagnosing and fixing the most dangerous silent breaking change in React 18 for class-component codebases.
用于诊断和修复React 18中针对类组件代码库最危险的静默破坏性变更的参考指南。

The Core Change

核心变更

Location of setStateReact 17React 18
React event handlerBatchedBatched (same)
setTimeoutImmediate re-renderBatched
Promise .then() / .catch()Immediate re-renderBatched
async/awaitImmediate re-renderBatched
Native addEventListener callbackImmediate re-renderBatched
Batched means: all setState calls within that execution context flush together in a single re-render at the end. No intermediate renders occur.
setState调用位置React 17React 18
React事件处理程序批处理批处理(无变化)
setTimeout立即重渲染批处理
Promise .then() / .catch()立即重渲染批处理
async/await立即重渲染批处理
原生addEventListener回调立即重渲染批处理
批处理指:该执行上下文中的所有setState调用会在执行结束时统一刷新,仅触发一次重渲染,不会产生中间渲染。

Quick Diagnosis

快速诊断

Read every async class method. Ask: does any code after an
await
read
this.state
to make a decision?
Code reads this.state after await?
  YES → Category A (silent state-read bug)
  NO, but intermediate render must be visible to user?
    YES → Category C (flushSync needed)
    NO → Category B (refactor, no flushSync)
For the full pattern for each category, read:
  • references/batching-categories.md
    - Category A, B, C with full before/after code
  • references/flushSync-guide.md
    - when to use flushSync, when NOT to, import syntax
遍历所有异步类方法,询问:
await
之后的代码是否会读取
this.state
来做决策?
Code reads this.state after await?
  YES → Category A (silent state-read bug)
  NO, but intermediate render must be visible to user?
    YES → Category C (flushSync needed)
    NO → Category B (refactor, no flushSync)
如需查看每个类别的完整模式,请阅读:
  • references/batching-categories.md
    - 包含A、B、C三类问题的完整前后对比代码
  • references/flushSync-guide.md
    - 何时使用/禁止使用flushSync,以及导入语法

The flushSync Rule

flushSync使用规则

Use
flushSync
sparingly.
It forces a synchronous re-render, bypassing React 18's concurrent scheduler. Overusing it negates the performance benefits of React 18.
Only use
flushSync
when:
  • The user must see an intermediate UI state before an async operation begins
  • A spinner/loading state must render before a fetch starts
  • Sequential UI steps have distinct visible states (progress wizard, multi-step flow)
In most cases, the fix is a refactor - restructuring the code to not read
this.state
after
await
. Read
references/batching-categories.md
for the correct approach per category.
谨慎使用
flushSync
。它会强制触发同步重渲染,绕过React 18的并发调度器。过度使用会抵消React 18带来的性能优势。
仅在以下场景使用
flushSync
  • 异步操作开始前,用户必须看到中间UI状态
  • 发起fetch请求前必须渲染 spinner/加载状态
  • 连续的UI步骤有不同的可见状态(进度向导、多步骤流程)
大多数情况下,修复方案是重构——调整代码结构,避免在
await
之后读取
this.state
。阅读
references/batching-categories.md
了解每个类别的正确处理方式。