react18-batching-patterns

Diagnose and fix automatic batching regressions in React 18 class components.

38.5k|4.9k|Updated Jun 11, 2025
One-click install
npx skills add https://github.com/github/awesome-copilot --skill react18-batching-patterns
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: react18-batching-patterns
Source: https://github.com/github/awesome-copilot/tree/main/skills/react18-batching-patterns
Command: npx skills add https://github.com/github/awesome-copilot --skill react18-batching-patterns

SYSTEM DOCUMENTATION & REQUIREMENTS

💡 This Skill includes references (resource) components.

What problem does it solve?

React 18 silently changed how setState behaves in async contexts: calls inside setTimeout, Promise .then()/.catch(), async/await, and native event handlers are now batched instead of triggering immediate re-renders. This causes silent bugs in class components that read this.state after an await, and breaks tests that assert intermediate states synchronously.

Core Features & Use Cases

  • Diagnostic Decision Tree: Classify any broken async setState pattern into Category A (silent this.state read bug), Category B (independent setState calls needing refactor), or Category C (intermediate render must be visible, requiring flushSync).
  • Before/After Fix Patterns: Concrete code rewrites for each category, including multi-step conditional chains, Promise chains, setTimeout autosave flows, and broken test assertions fixed with waitFor.
  • flushSync Usage Guide: Exact import syntax (from react-dom, not react), when to use it, when not to, and performance warnings against overuse.
  • Use Case: After upgrading a codebase to React 18, a loading spinner never appears and a conditional update silently never fires. Use this Skill to identify it as a Category A bug and rewrite the method to remove the this.state read after await.

Quick Start

Ask the AI to diagnose why a class component's setState calls inside an async method stopped re-rendering after upgrading to React 18.

Frequently Asked Questions about react18-batching-patterns

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
Why does setState not re-render immediately in React 18 async functions?

React 18 batches all setState calls inside async contexts like await, setTimeout, and Promise handlers, so no intermediate re-render occurs. In React 17 these contexts triggered immediate re-renders, which is why code reading this.state after an await now sees stale values.

How do I fix this.state returning old values after await in React 18?

Remove the this.state read after the await instead of adding flushSync. If the condition was always going to be true, delete it and call setState unconditionally; for multi-step flows, track progress with local variables rather than component state.

When should I use flushSync in React 18?

Use flushSync only when the user must see an intermediate UI state, like a loading spinner, before an async operation starts. Import it from react-dom, wrap the setState call, and avoid using it to fix state-read bugs or for every setState call.

Why do my React tests fail after upgrading to React 18?

Tests that synchronously assert intermediate states break because batching defers those renders. Make the test async and wrap assertions in waitFor so the batched update has time to flush before checking the DOM.

Does flushSync hurt React 18 performance?

Yes, flushSync forces a synchronous render that blocks the browser thread and bypasses concurrent scheduling. Using more than two flushSync calls in one method can cause visible jank and usually signals the state model needs redesign.