mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Test cases for inferring mutability of function expressions (as values)
This PR contains just the test cases from #1717, showing some tricky cases around function expression mutability inference.
This commit is contained in:
+27
@@ -0,0 +1,27 @@
|
||||
|
||||
## Input
|
||||
|
||||
```javascript
|
||||
function Component(props) {
|
||||
let x = {};
|
||||
// onChange should be inferred as immutable, because the value
|
||||
// it captures (`x`) is frozen by the time the function is referenced
|
||||
const onChange = (e) => {
|
||||
maybeMutate(x, e.target.value);
|
||||
};
|
||||
if (props.cond) {
|
||||
<div>{x}</div>;
|
||||
}
|
||||
return <Foo value={x} onChange={onChange} />;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
|
||||
## Error
|
||||
|
||||
```
|
||||
[ReactForget] InvalidInput: Cannot use a mutable function where an immutable value is expected (11:11)
|
||||
```
|
||||
|
||||
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
function Component(props) {
|
||||
let x = {};
|
||||
// onChange should be inferred as immutable, because the value
|
||||
// it captures (`x`) is frozen by the time the function is referenced
|
||||
const onChange = (e) => {
|
||||
maybeMutate(x, e.target.value);
|
||||
};
|
||||
if (props.cond) {
|
||||
<div>{x}</div>;
|
||||
}
|
||||
return <Foo value={x} onChange={onChange} />;
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
|
||||
## Input
|
||||
|
||||
```javascript
|
||||
function Component(props) {
|
||||
const id = useSelectedEntitytId();
|
||||
// this example should infer `id` as mutable, and then infer `onLoad` as mutable,
|
||||
// and be rejected because onLoad cannot be passed as a frozen value in the JSX.
|
||||
// however, we likely have to allow this example to work, because hook return
|
||||
// values are generally immutable in practice and are also widely referenced in
|
||||
// callbacks.
|
||||
const onLoad = () => {
|
||||
log(id);
|
||||
};
|
||||
return <Foo onLoad={onLoad} />;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
|
||||
## Error
|
||||
|
||||
```
|
||||
[ReactForget] InvalidInput: Cannot use a mutable function where an immutable value is expected (11:11)
|
||||
```
|
||||
|
||||
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
function Component(props) {
|
||||
const id = useSelectedEntitytId();
|
||||
// this example should infer `id` as mutable, and then infer `onLoad` as mutable,
|
||||
// and be rejected because onLoad cannot be passed as a frozen value in the JSX.
|
||||
// however, we likely have to allow this example to work, because hook return
|
||||
// values are generally immutable in practice and are also widely referenced in
|
||||
// callbacks.
|
||||
const onLoad = () => {
|
||||
log(id);
|
||||
};
|
||||
return <Foo onLoad={onLoad} />;
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
|
||||
## Input
|
||||
|
||||
```javascript
|
||||
function Component(props) {
|
||||
let x = {};
|
||||
// onChange should be inferred as immutable, because the value
|
||||
// it captures (`x`) is frozen by the time the function is referenced
|
||||
const onChange = (e) => {
|
||||
maybeMutate(x, e.target.value);
|
||||
};
|
||||
if (props.cond) {
|
||||
<div>{x}</div>;
|
||||
}
|
||||
// ideally this call would be outside the memoization block for `x`
|
||||
onChange();
|
||||
return <Foo value={x} />;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Code
|
||||
|
||||
```javascript
|
||||
import { unstable_useMemoCache as useMemoCache } from "react";
|
||||
function Component(props) {
|
||||
const $ = useMemoCache(4);
|
||||
const c_0 = $[0] !== props.cond;
|
||||
let x;
|
||||
if (c_0) {
|
||||
x = {};
|
||||
|
||||
const onChange = (e) => {
|
||||
maybeMutate(x, e.target.value);
|
||||
};
|
||||
if (props.cond) {
|
||||
}
|
||||
|
||||
onChange();
|
||||
$[0] = props.cond;
|
||||
$[1] = x;
|
||||
} else {
|
||||
x = $[1];
|
||||
}
|
||||
const c_2 = $[2] !== x;
|
||||
let t0;
|
||||
if (c_2) {
|
||||
t0 = <Foo value={x} />;
|
||||
$[2] = x;
|
||||
$[3] = t0;
|
||||
} else {
|
||||
t0 = $[3];
|
||||
}
|
||||
return t0;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
function Component(props) {
|
||||
let x = {};
|
||||
// onChange should be inferred as immutable, because the value
|
||||
// it captures (`x`) is frozen by the time the function is referenced
|
||||
const onChange = (e) => {
|
||||
maybeMutate(x, e.target.value);
|
||||
};
|
||||
if (props.cond) {
|
||||
<div>{x}</div>;
|
||||
}
|
||||
// ideally this call would be outside the memoization block for `x`
|
||||
onChange();
|
||||
return <Foo value={x} />;
|
||||
}
|
||||
Reference in New Issue
Block a user