mirror of
https://github.com/react/react.git
synced 2026-09-28 21:25:11 +08:00
`react-hooks/set-state-in-effect` flagged setState calls that happen after an `await` inside an async function invoked from an effect. Post-await code resumes in a microtask after the effect body has returned, so the "synchronous setState cascades a render" rationale does not apply; the lint was a false positive on a common data-loading shape (15 reactions on the issue). The fix exempts a setState only when it is *provably* post-await: a forward must-dataflow over the HIR CFG computes the blocks that begin after an await has executed on every path from the function entry (optimistic initialization so loop back-edges do not pessimize the meet, fixpoint to the greatest solution), plus an intra-block flag for instructions after an Await in the same block. A setState reachable on any await-free path still flags, so the conditional-await case remains an error by design, with a fixture documenting that choice. Suppression is sound under try/catch because HIRBuilder terminates blocks after each instruction in a try region, and an awaited rejection also resumes in a microtask. Fixtures: post-await setState (event gone), setState before the first await (still flags), setState after a conditional await (still flags). First commit documents the false positive via the lint-mode logger output, second removes it. Builds on the approach in #36417 by @raashish1601, hardened from a seen-await flag to the path-sensitive analysis above. Implemented identically in the TypeScript compiler and the Rust port. Verification: TS snap 1807/1807, Rust snap 1807/1807, cargo workspace green, scoped TS-vs-Rust HIR parity harness green. Closes #34905 --------- Co-authored-by: Raashish Aggarwal <94279692+raashish1601@users.noreply.github.com>