mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Extra test case related to memoization "within" freeze
I found an interesting edge case in the previous diff with mutation of a value
that appears in the expression of an object key:
```javascript
const key = {}
const object = {
[mutateAndReturnOtherValue(key)]: 42,
};
mutate(key);
```
We analyze and represent this correctly all the way through to codegen, but then
we hit the bug that @mofeiZ has noticed before: the temporary for `t =
mutateAndReturnOtherValue(key)` isn't emitted immediately (bc its a temporary).
It gets emitted inside the memo block for `object`, which is incorrect.
I tried to reproduce that here with JSX and it works as expected. It's an
interesting case though so let's land this to ensure we don't regress.
This commit is contained in:
+53
@@ -0,0 +1,53 @@
|
||||
|
||||
## Input
|
||||
|
||||
```javascript
|
||||
import { identity, mutate, mutateAndReturnNewValue } from "shared-runtime";
|
||||
|
||||
function Component(props) {
|
||||
const key = {};
|
||||
// Key is modified by the function, but key itself is not frozen
|
||||
const element = <div key={mutateAndReturnNewValue(key)}>{props.value}</div>;
|
||||
// Key is later mutated here: this mutation must be grouped with the
|
||||
// jsx construction above
|
||||
mutate(key);
|
||||
return element;
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
fn: Component,
|
||||
params: [{ value: 42 }],
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
## Code
|
||||
|
||||
```javascript
|
||||
import { unstable_useMemoCache as useMemoCache } from "react";
|
||||
import { identity, mutate, mutateAndReturnNewValue } from "shared-runtime";
|
||||
|
||||
function Component(props) {
|
||||
const $ = useMemoCache(2);
|
||||
let element;
|
||||
if ($[0] !== props.value) {
|
||||
const key = {};
|
||||
|
||||
element = <div key={mutateAndReturnNewValue(key)}>{props.value}</div>;
|
||||
|
||||
mutate(key);
|
||||
$[0] = props.value;
|
||||
$[1] = element;
|
||||
} else {
|
||||
element = $[1];
|
||||
}
|
||||
return element;
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
fn: Component,
|
||||
params: [{ value: 42 }],
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
import { identity, mutate, mutateAndReturnNewValue } from "shared-runtime";
|
||||
|
||||
function Component(props) {
|
||||
const key = {};
|
||||
// Key is modified by the function, but key itself is not frozen
|
||||
const element = <div key={mutateAndReturnNewValue(key)}>{props.value}</div>;
|
||||
// Key is later mutated here: this mutation must be grouped with the
|
||||
// jsx construction above
|
||||
mutate(key);
|
||||
return element;
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
fn: Component,
|
||||
params: [{ value: 42 }],
|
||||
};
|
||||
@@ -73,6 +73,11 @@ export function mutateAndReturn<T>(arg: T): T {
|
||||
return arg;
|
||||
}
|
||||
|
||||
export function mutateAndReturnNewValue<T>(arg: T): string {
|
||||
mutate(arg);
|
||||
return "hello!";
|
||||
}
|
||||
|
||||
export function setProperty(arg: any, property: any): void {
|
||||
// don't mutate primitive
|
||||
if (typeof arg === null || typeof arg !== "object") {
|
||||
|
||||
Reference in New Issue
Block a user