react icon indicating copy to clipboard operation
react copied to clipboard

[compiler] Fix `set-state-in-effect` validation for `React.useEffect`

Open jynxio opened this issue 3 months ago • 0 comments

Summary

I noticed that React.useEffect bypasses the set-state-in-effect validation, as shown below (or see this CodeSandbox).

// ✅ ESLint error reported (refer to: react-hooks/set-state-in-effect)
useEffect(() => setState(s => s + 1), []);

// ❌ No ESLint error, but it should have
React.useEffect(() => setState(s => s + 1), []);

Initially I thought this was an eslint-plugin-react-hooks issue, but later realized it's a Compiler-level bug.

The bug was in the callee extraction for MethodCall: it checked receiver (the React namespace) instead of property (the useEffect method). Since React is not an effect hook, the validation was skipped.

The fix changes instr.value.receiver to instr.value.property so that useEffect is correctly identified as an effect hook.

 const callee =
   instr.value.kind === 'MethodCall'
-    ? instr.value.receiver
+    ? instr.value.property
     : instr.value.callee;


How did you test this change?

  1. Added a React.useEffect case to invalid-setState-in-useEffect.js.

  2. Updated invalid-setState-in-useEffect.expect.md and checked the Logs: only one CompileError at line 7, missing React.useEffect at line 10. (See Commit 1)

  3. Fixed ValidateNoSetStateInEffects.ts.

  4. Updated invalid-setState-in-useEffect.expect.md again and checked the Logs: now two CompileErrors are reported (line 7 and line 10). (See Commit 2)

  5. Ran and passed all tests in compiler/packages/babel-plugin-react-compiler (yarn snap:ci).

jynxio avatar Dec 03 '25 17:12 jynxio