mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Repro for "context variables are always mutable" error w callbacks
I haven't debugged to understand exactly why this pattern fails, but there are a
few instances of this internally. It's especially weird because
```javascript
// @enableAssumeHooksFollowRulesOfReact
@enableTransitivelyFreezeFunctionExpressions
function Component(props) {
const [_state, setState] = useState();
const a = () => {
return b();
};
const b = () => {
return (
<>
<div onClick={() => onClick(true)} />
<div onClick={() => onClick(false)} /> // <---- only repros if there's a second
call!
</>
);
};
const onClick = (value) => {
setState(value);
};
return <div>{a()}</div>;
}
```
Here, if `b()` only had one nested function expression that called `onClick` it
would work. Also, if we disable `@enableTransitivelyFreezeFunctionExpressions`
then it works.
But the combination of multiple calls plus that mode causes "context variables
are always mutable". I'm guessing we're freezing `onClick` twice and the second
time reports an error since it calls `setState`.
This commit is contained in:
+46
@@ -0,0 +1,46 @@
|
||||
|
||||
## Input
|
||||
|
||||
```javascript
|
||||
// @enableAssumeHooksFollowRulesOfReact @enableTransitivelyFreezeFunctionExpressions
|
||||
function Component(props) {
|
||||
const [_state, setState] = useState();
|
||||
const a = () => {
|
||||
return b();
|
||||
};
|
||||
const b = () => {
|
||||
return (
|
||||
<>
|
||||
<div onClick={() => onClick(true)} />
|
||||
<div onClick={() => onClick(false)} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
const onClick = (value) => {
|
||||
setState(value);
|
||||
};
|
||||
|
||||
return <div>{a()}</div>;
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPONT = {
|
||||
fn: Component,
|
||||
props: [{}],
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
|
||||
## Error
|
||||
|
||||
```
|
||||
9 | <>
|
||||
10 | <div onClick={() => onClick(true)} />
|
||||
> 11 | <div onClick={() => onClick(false)} />
|
||||
| ^^^^^^^ [ReactForget] Invariant: [InferReferenceEffects] Context variables are always mutable. (11:11)
|
||||
12 | </>
|
||||
13 | );
|
||||
14 | };
|
||||
```
|
||||
|
||||
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
// @enableAssumeHooksFollowRulesOfReact @enableTransitivelyFreezeFunctionExpressions
|
||||
function Component(props) {
|
||||
const [_state, setState] = useState();
|
||||
const a = () => {
|
||||
return b();
|
||||
};
|
||||
const b = () => {
|
||||
return (
|
||||
<>
|
||||
<div onClick={() => onClick(true)} />
|
||||
<div onClick={() => onClick(false)} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
const onClick = (value) => {
|
||||
setState(value);
|
||||
};
|
||||
|
||||
return <div>{a()}</div>;
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPONT = {
|
||||
fn: Component,
|
||||
props: [{}],
|
||||
};
|
||||
Reference in New Issue
Block a user