Open
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
Loving the compiler so far! Here's a bit of an inconsistency I've discovered - apologies if it's been brought up elsewhere.
If a function:
- is defined in the body of a component
- returns a primitive value, instead of an object
calls to it won't be memoized, even if it's particularly expensive.
Here's an example of what I mean: expensiveComputation
is called every render (i.e. every time the button is clicked).
function Bad() {
const [counter, setCounter] = useState(0);
function expensiveComputation() {
for (let i = 0; i < 9999; i++) {
}
return 3;
}
// Computed each render!
const expensiveValue = expensiveComputation();
return <button onClick={() => setCounter(n => n + 1)}>Count: {counter} {expensiveValue}</button>
}
What's interesting is that the function reference itself is actually memoized - it's just calls to it that aren't.
let t0;
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
t0 = function expensiveComputation() {
for (let i = 0; i < 9999; i++) {}
return 3;
};
$[0] = t0;
} else {
t0 = $[0];
}
const expensiveComputation = t0;
Again, this issue does not occur if the function returns an object:
function Good() {
const [counter, setCounter] = useState(0);
function expensiveComputation() {
for (let i = 0; i < 9999; i++) {
}
return { value: 3 };
}
// Not computed each render!
const expensiveValue = expensiveComputation();
return <button onClick={() => setCounter(n => n + 1)}>Count: {counter} {expensiveValue.value}</button>
}
Or if the function is defined outside the component:
function AlsoGood() {
const [counter, setCounter] = useState(0);
// Not computed each render!
const expensiveValue = expensiveComputation();
return <button onClick={() => setCounter(n => n + 1)}>Count: {counter} {expensiveValue}</button>
}
function expensiveComputation() {
for (let i = 0; i < 9999; i++) {
}
return 3;
}
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.2