Description
What kind of issue is this?
- React Compiler core (the JS output is incorrect, or your app works incorrectly after optimization)
- babel-plugin-react-compiler (build issue installing or using the Babel plugin)
- eslint-plugin-react-compiler (build issue installing or using the eslint plugin)
- react-compiler-healthcheck (build issue installing or using the healthcheck script)
Link to repro
Repro steps
Currently, the React compiler memoizes parameters passed to hooks if those parameters are non-primitives. This behavior appears to be applied universally, regardless of whether the hook is a built-in (native) React hook or a custom one.
However, for most native hooks, this memoization is unnecessary. It results in increased output code size and adds runtime overhead without any meaningful benefit.
Examples
Input code using useRef
:
const ref = useRef({ value });
Compiled output:
let t1;
if ($[0] !== value) {
t1 = { value };
$[0] = value;
$[1] = t1;
} else {
t1 = $[1];
}
const ref = useRef(t1);
Input code using useState
:
const [state, setState] = useState({ value });
Compiled output:
let t2;
if ($[2] !== value) {
t2 = { value };
$[2] = value;
$[3] = t2;
} else {
t2 = $[3];
}
const [state, setState] = useState(t2);
In both examples, the memoization of the initial values passed to the native hooks is unnecessary.
This same pattern of memoization is also applied to other built-in hooks such as useReducer
and useEffect
Expected behavior
The compiler should treat native hooks differently and avoid memoizing parameters when it's not needed. This would reduce both the generated code size and runtime overhead.
How often does this bug happen?
Every time
What version of React are you using?
19.1.0
What version of React Compiler are you using?
19.1.0-rc.1