mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
[dx] Improve error messages for unpreserved memoization
ghstack-source-id: ff5bcaa7ab219035f57dc3dc3396c9a324896d4b Pull Request resolved: https://github.com/facebook/react-forget/pull/2869
This commit is contained in:
@@ -23,7 +23,7 @@ export enum ErrorSeverity {
|
||||
*/
|
||||
InvalidConfig = "InvalidConfig",
|
||||
/**
|
||||
* Code that can reasonably occur and that doesn't break any rules, but is unsafe to perserve
|
||||
* Code that can reasonably occur and that doesn't break any rules, but is unsafe to preserve
|
||||
* memoization.
|
||||
*/
|
||||
CannotPreserveMemoization = "CannotPreserveMemoization",
|
||||
|
||||
+2
-2
@@ -104,9 +104,9 @@ class Visitor extends ReactiveFunctionVisitor<CompilerError> {
|
||||
) {
|
||||
state.push({
|
||||
reason:
|
||||
"This effect may trigger an infinite loop: one or more of its dependencies could not be memoized due to a later mutation",
|
||||
"React Compiler has skipped optimizing this component because the effect dependencies could not be memoized. Unmemoized effect dependencies can trigger an infinite loop or other unexpected behavior",
|
||||
description: null,
|
||||
severity: ErrorSeverity.InvalidReact,
|
||||
severity: ErrorSeverity.CannotPreserveMemoization,
|
||||
loc: typeof instruction.loc !== "symbol" ? instruction.loc : null,
|
||||
suggestions: null,
|
||||
});
|
||||
|
||||
+26
-15
@@ -20,6 +20,7 @@ import {
|
||||
ReactiveScopeDependency,
|
||||
ReactiveValue,
|
||||
ScopeId,
|
||||
SourceLocation,
|
||||
} from "../HIR";
|
||||
import { printManualMemoDependency } from "../HIR/PrintHIR";
|
||||
import { eachInstructionValueOperand } from "../HIR/visitors";
|
||||
@@ -48,7 +49,12 @@ export function validatePreservedManualMemoization(fn: ReactiveFunction): void {
|
||||
}
|
||||
}
|
||||
|
||||
const DEBUG = false;
|
||||
|
||||
type ManualMemoBlockState = {
|
||||
// The source of the original memoization, used when reporting errors
|
||||
loc: SourceLocation;
|
||||
|
||||
/**
|
||||
* Values produced within manual memoization blocks.
|
||||
* We track these to ensure our inferred dependencies are
|
||||
@@ -201,7 +207,8 @@ function validateInferredDep(
|
||||
temporaries: Map<IdentifierId, ManualMemoDependency>,
|
||||
declsWithinMemoBlock: Set<IdentifierId>,
|
||||
validDepsInMemoBlock: Array<ManualMemoDependency>,
|
||||
errorState: CompilerError
|
||||
errorState: CompilerError,
|
||||
memoLocation: SourceLocation
|
||||
): void {
|
||||
let normalizedDep: ManualMemoDependency;
|
||||
const maybeNormalizedRoot = temporaries.get(dep.identifier.id);
|
||||
@@ -249,19 +256,21 @@ function validateInferredDep(
|
||||
}
|
||||
}
|
||||
errorState.push({
|
||||
severity: ErrorSeverity.Todo,
|
||||
severity: ErrorSeverity.CannotPreserveMemoization,
|
||||
reason:
|
||||
"Could not preserve manual memoization because an inferred dependency does not match the dependency list in source",
|
||||
description: `The inferred dependency was \`${prettyPrintScopeDependency(
|
||||
dep
|
||||
)}\`, but the source dependencies were [${validDepsInMemoBlock
|
||||
.map((dep) => printManualMemoDependency(dep, true))
|
||||
.join(", ")}]. Detail: ${
|
||||
errorDiagnostic
|
||||
? getCompareDependencyResultDescription(errorDiagnostic)
|
||||
: "none"
|
||||
}`,
|
||||
loc: GeneratedSource,
|
||||
"React Compiler has skipped optimizing this component because the existing manual memoization could not be preserved. The inferred dependencies did not match the manually specified dependencies, which could cause the value to change more or less frequently than expected",
|
||||
description: DEBUG
|
||||
? `The inferred dependency was \`${prettyPrintScopeDependency(
|
||||
dep
|
||||
)}\`, but the source dependencies were [${validDepsInMemoBlock
|
||||
.map((dep) => printManualMemoDependency(dep, true))
|
||||
.join(", ")}]. Detail: ${
|
||||
errorDiagnostic
|
||||
? getCompareDependencyResultDescription(errorDiagnostic)
|
||||
: "none"
|
||||
}`
|
||||
: null,
|
||||
loc: memoLocation,
|
||||
suggestions: null,
|
||||
});
|
||||
}
|
||||
@@ -359,7 +368,8 @@ class Visitor extends ReactiveFunctionVisitor<VisitorState> {
|
||||
this.temporaries,
|
||||
state.manualMemoState.decls,
|
||||
state.manualMemoState.depsFromSource,
|
||||
state.errors
|
||||
state.errors,
|
||||
state.manualMemoState.loc
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -405,6 +415,7 @@ class Visitor extends ReactiveFunctionVisitor<VisitorState> {
|
||||
});
|
||||
|
||||
state.manualMemoState = {
|
||||
loc: instruction.loc,
|
||||
decls: new Set(),
|
||||
depsFromSource,
|
||||
manualMemoId: instruction.value.manualMemoId,
|
||||
@@ -437,7 +448,7 @@ class Visitor extends ReactiveFunctionVisitor<VisitorState> {
|
||||
) {
|
||||
state.errors.push({
|
||||
reason:
|
||||
"This value was manually memoized, but cannot be memoized under Forget because it may be mutated after it is memoized",
|
||||
"React Compiler has skipped optimizing this component because the existing manual memoization could not be preserved. This value may be mutated later, which could cause the value to change unexpectedly",
|
||||
description: null,
|
||||
severity: ErrorSeverity.CannotPreserveMemoization,
|
||||
loc: typeof instruction.loc !== "symbol" ? instruction.loc : null,
|
||||
|
||||
+1
-1
@@ -30,7 +30,7 @@ function Component(props) {
|
||||
> 10 | console.log(items);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
> 11 | }, [items]);
|
||||
| ^^^^^^^^^^^^^^ InvalidReact: This effect may trigger an infinite loop: one or more of its dependencies could not be memoized due to a later mutation (9:11)
|
||||
| ^^^^^^^^^^^^^^ CannotPreserveMemoization: React Compiler has skipped optimizing this component because the effect dependencies could not be memoized. Unmemoized effect dependencies can trigger an infinite loop or other unexpected behavior (9:11)
|
||||
12 |
|
||||
13 | return [items, state];
|
||||
14 | }
|
||||
|
||||
+1
-1
@@ -27,7 +27,7 @@ function Component(props) {
|
||||
> 7 | console.log(props.value);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
> 8 | }, [data]);
|
||||
| ^^^^^^^^^^^^^ InvalidReact: This effect may trigger an infinite loop: one or more of its dependencies could not be memoized due to a later mutation (6:8)
|
||||
| ^^^^^^^^^^^^^ CannotPreserveMemoization: React Compiler has skipped optimizing this component because the effect dependencies could not be memoized. Unmemoized effect dependencies can trigger an infinite loop or other unexpected behavior (6:8)
|
||||
9 | mutate(data);
|
||||
10 | return data;
|
||||
11 | }
|
||||
|
||||
+1
-1
@@ -27,7 +27,7 @@ function Component(props) {
|
||||
> 7 | console.log(props.value);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
> 8 | }, [data]);
|
||||
| ^^^^^^^^^^^^^ InvalidReact: This effect may trigger an infinite loop: one or more of its dependencies could not be memoized due to a later mutation (6:8)
|
||||
| ^^^^^^^^^^^^^ CannotPreserveMemoization: React Compiler has skipped optimizing this component because the effect dependencies could not be memoized. Unmemoized effect dependencies can trigger an infinite loop or other unexpected behavior (6:8)
|
||||
9 | mutate(data);
|
||||
10 | return data;
|
||||
11 | }
|
||||
|
||||
+1
-1
@@ -27,7 +27,7 @@ function Component(props) {
|
||||
> 7 | console.log(props.value);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
> 8 | }, [data]);
|
||||
| ^^^^^^^^^^^^^ InvalidReact: This effect may trigger an infinite loop: one or more of its dependencies could not be memoized due to a later mutation (6:8)
|
||||
| ^^^^^^^^^^^^^ CannotPreserveMemoization: React Compiler has skipped optimizing this component because the effect dependencies could not be memoized. Unmemoized effect dependencies can trigger an infinite loop or other unexpected behavior (6:8)
|
||||
9 | mutate(data);
|
||||
10 | return data;
|
||||
11 | }
|
||||
|
||||
+1
-1
@@ -53,7 +53,7 @@ export const FIXTURE_ENTRYPOINT = {
|
||||
9 | const a = useHook();
|
||||
10 | // Because b is also part of that same mutable range, it can't be memoized either
|
||||
> 11 | const b = useMemo(() => ({}), []);
|
||||
| ^^^^^^^^^^ CannotPreserveMemoization: This value was manually memoized, but cannot be memoized under Forget because it may be mutated after it is memoized (11:11)
|
||||
| ^^^^^^^^^^ CannotPreserveMemoization: React Compiler has skipped optimizing this component because the existing manual memoization could not be preserved. This value may be mutated later, which could cause the value to change unexpectedly (11:11)
|
||||
12 |
|
||||
13 | // Conditional assignment without a subsequent mutation normally doesn't create a mutable
|
||||
14 | // range, but in this case we're reassigning a context variable
|
||||
|
||||
+1
-1
@@ -45,7 +45,7 @@ export const FIXTURE_ENTRYPOINT = {
|
||||
> 10 | ref.current.inner = event.target.value;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
> 11 | });
|
||||
| ^^^^ CannotPreserveMemoization: This value was manually memoized, but cannot be memoized under Forget because it may be mutated after it is memoized (7:11)
|
||||
| ^^^^ CannotPreserveMemoization: React Compiler has skipped optimizing this component because the existing manual memoization could not be preserved. This value may be mutated later, which could cause the value to change unexpectedly (7:11)
|
||||
12 |
|
||||
13 | // The ref is modified later, extending its range and preventing memoization of onChange
|
||||
14 | const reset = () => {
|
||||
|
||||
+1
-1
@@ -42,7 +42,7 @@ export const FIXTURE_ENTRYPOINT = {
|
||||
> 10 | ref.current.inner = event.target.value;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
> 11 | });
|
||||
| ^^^^ CannotPreserveMemoization: This value was manually memoized, but cannot be memoized under Forget because it may be mutated after it is memoized (7:11)
|
||||
| ^^^^ CannotPreserveMemoization: React Compiler has skipped optimizing this component because the existing manual memoization could not be preserved. This value may be mutated later, which could cause the value to change unexpectedly (7:11)
|
||||
12 |
|
||||
13 | // The ref is modified later, extending its range and preventing memoization of onChange
|
||||
14 | ref.current.inner = null;
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ export const FIXTURE_ENTRYPOINT = {
|
||||
> 12 | console.log(y);
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
> 13 | }, [y]);
|
||||
| ^^^^^^^^^^ InvalidReact: This effect may trigger an infinite loop: one or more of its dependencies could not be memoized due to a later mutation (11:13)
|
||||
| ^^^^^^^^^^ CannotPreserveMemoization: React Compiler has skipped optimizing this component because the effect dependencies could not be memoized. Unmemoized effect dependencies can trigger an infinite loop or other unexpected behavior (11:13)
|
||||
14 | }
|
||||
15 |
|
||||
16 | export const FIXTURE_ENTRYPOINT = {
|
||||
|
||||
+1
-1
@@ -36,7 +36,7 @@ export const FIXTURE_ENTRYPOINT = {
|
||||
> 13 | return identity(val);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
> 14 | }, [val]);
|
||||
| ^^^^ CannotPreserveMemoization: This value was manually memoized, but cannot be memoized under Forget because it may be mutated after it is memoized (12:14)
|
||||
| ^^^^ CannotPreserveMemoization: React Compiler has skipped optimizing this component because the existing manual memoization could not be preserved. This value may be mutated later, which could cause the value to change unexpectedly (12:14)
|
||||
15 | }
|
||||
16 |
|
||||
17 | export const FIXTURE_ENTRYPOINT = {
|
||||
|
||||
+2
-2
@@ -33,9 +33,9 @@ export const FIXTURE_ENTRYPOINT = {
|
||||
10 |
|
||||
11 | // makeArray() is captured, but depsList contains [props]
|
||||
> 12 | const cb = useCallback(() => [x], [x]);
|
||||
| ^^^^^^^^^ CannotPreserveMemoization: This value was manually memoized, but cannot be memoized under Forget because it may be mutated after it is memoized (12:12)
|
||||
| ^^^^^^^^^ CannotPreserveMemoization: React Compiler has skipped optimizing this component because the existing manual memoization could not be preserved. This value may be mutated later, which could cause the value to change unexpectedly (12:12)
|
||||
|
||||
CannotPreserveMemoization: This value was manually memoized, but cannot be memoized under Forget because it may be mutated after it is memoized (12:12)
|
||||
CannotPreserveMemoization: React Compiler has skipped optimizing this component because the existing manual memoization could not be preserved. This value may be mutated later, which could cause the value to change unexpectedly (12:12)
|
||||
13 |
|
||||
14 | x = makeArray();
|
||||
15 |
|
||||
|
||||
+10
-1
@@ -17,7 +17,16 @@ function useHook(maybeRef) {
|
||||
## Error
|
||||
|
||||
```
|
||||
Todo: Could not preserve manual memoization because an inferred dependency does not match the dependency list in source. The inferred dependency was `maybeRef.current`, but the source dependencies were [maybeRef]. Detail: differences in ref.current access
|
||||
3 |
|
||||
4 | function useHook(maybeRef) {
|
||||
> 5 | return useCallback(() => {
|
||||
| ^^^^^^^
|
||||
> 6 | return [maybeRef.current];
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
> 7 | }, [maybeRef]);
|
||||
| ^^^^ CannotPreserveMemoization: React Compiler has skipped optimizing this component because the existing manual memoization could not be preserved. The inferred dependencies did not match the manually specified dependencies, which could cause the value to change more or less frequently than expected (5:7)
|
||||
8 | }
|
||||
9 |
|
||||
```
|
||||
|
||||
|
||||
+10
-1
@@ -17,7 +17,16 @@ function useHook(maybeRef, shouldRead) {
|
||||
## Error
|
||||
|
||||
```
|
||||
Todo: Could not preserve manual memoization because an inferred dependency does not match the dependency list in source. The inferred dependency was `maybeRef.current`, but the source dependencies were [shouldRead, maybeRef]. Detail: differences in ref.current access
|
||||
3 |
|
||||
4 | function useHook(maybeRef, shouldRead) {
|
||||
> 5 | return useMemo(() => {
|
||||
| ^^^^^^^
|
||||
> 6 | return () => [maybeRef.current];
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
> 7 | }, [shouldRead, maybeRef]);
|
||||
| ^^^^ CannotPreserveMemoization: React Compiler has skipped optimizing this component because the existing manual memoization could not be preserved. The inferred dependencies did not match the manually specified dependencies, which could cause the value to change more or less frequently than expected (5:7)
|
||||
8 | }
|
||||
9 |
|
||||
```
|
||||
|
||||
|
||||
+1
-1
@@ -31,7 +31,7 @@ export const FIXTURE_ENTRYPOINT = {
|
||||
11 | x.push(props);
|
||||
12 |
|
||||
> 13 | return useCallback(() => [x], [x]);
|
||||
| ^^^^^^^^^ CannotPreserveMemoization: This value was manually memoized, but cannot be memoized under Forget because it may be mutated after it is memoized (13:13)
|
||||
| ^^^^^^^^^ CannotPreserveMemoization: React Compiler has skipped optimizing this component because the existing manual memoization could not be preserved. This value may be mutated later, which could cause the value to change unexpectedly (13:13)
|
||||
14 | }
|
||||
15 |
|
||||
16 | export const FIXTURE_ENTRYPOINT = {
|
||||
|
||||
+6
-1
@@ -19,7 +19,12 @@ function useHook(x) {
|
||||
## Error
|
||||
|
||||
```
|
||||
Todo: Could not preserve manual memoization because an inferred dependency does not match the dependency list in source. The inferred dependency was `aliasedX`, but the source dependencies were [x, aliasedProp]. Detail: inferred different dependency than source
|
||||
7 | const aliasedProp = x.y.z;
|
||||
8 |
|
||||
> 9 | return useCallback(() => [aliasedX, x.y.z], [x, aliasedProp]);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ CannotPreserveMemoization: React Compiler has skipped optimizing this component because the existing manual memoization could not be preserved. The inferred dependencies did not match the manually specified dependencies, which could cause the value to change more or less frequently than expected (9:9)
|
||||
10 | }
|
||||
11 |
|
||||
```
|
||||
|
||||
|
||||
+17
-1
@@ -25,7 +25,23 @@ export const FIXTURE_ENTRYPOINT = {
|
||||
## Error
|
||||
|
||||
```
|
||||
Todo: Could not preserve manual memoization because an inferred dependency does not match the dependency list in source. The inferred dependency was `propB`, but the source dependencies were [propA, propB.x.y]. Detail: inferred less specific property than source
|
||||
3 |
|
||||
4 | function Component({ propA, propB }) {
|
||||
> 5 | return useCallback(() => {
|
||||
| ^^^^^^^
|
||||
> 6 | return {
|
||||
| ^^^^^^^^^^^^
|
||||
> 7 | value: propB?.x.y,
|
||||
| ^^^^^^^^^^^^
|
||||
> 8 | other: propA,
|
||||
| ^^^^^^^^^^^^
|
||||
> 9 | };
|
||||
| ^^^^^^^^^^^^
|
||||
> 10 | }, [propA, propB.x.y]);
|
||||
| ^^^^ CannotPreserveMemoization: React Compiler has skipped optimizing this component because the existing manual memoization could not be preserved. The inferred dependencies did not match the manually specified dependencies, which could cause the value to change more or less frequently than expected (5:10)
|
||||
11 | }
|
||||
12 |
|
||||
13 | export const FIXTURE_ENTRYPOINT = {
|
||||
```
|
||||
|
||||
|
||||
+22
-1
@@ -24,7 +24,28 @@ function Component({ propA, propB }) {
|
||||
## Error
|
||||
|
||||
```
|
||||
Todo: Could not preserve manual memoization because an inferred dependency does not match the dependency list in source. The inferred dependency was `propA`, but the source dependencies were [propA.a, propB.x.y]. Detail: inferred less specific property than source
|
||||
4 |
|
||||
5 | function Component({ propA, propB }) {
|
||||
> 6 | return useCallback(() => {
|
||||
| ^^^^^^^
|
||||
> 7 | const x = {};
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
> 8 | if (propA?.a) {
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
> 9 | mutate(x);
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
> 10 | return {
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
> 11 | value: propB.x.y,
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
> 12 | };
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
> 13 | }
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
> 14 | }, [propA?.a, propB.x.y]);
|
||||
| ^^^^ CannotPreserveMemoization: React Compiler has skipped optimizing this component because the existing manual memoization could not be preserved. The inferred dependencies did not match the manually specified dependencies, which could cause the value to change more or less frequently than expected (6:14)
|
||||
15 | }
|
||||
16 |
|
||||
```
|
||||
|
||||
|
||||
+10
-1
@@ -17,7 +17,16 @@ function Component({ propA }) {
|
||||
## Error
|
||||
|
||||
```
|
||||
Todo: Could not preserve manual memoization because an inferred dependency does not match the dependency list in source. The inferred dependency was `propA`, but the source dependencies were [propA.x]. Detail: inferred less specific property than source
|
||||
3 |
|
||||
4 | function Component({ propA }) {
|
||||
> 5 | return useCallback(() => {
|
||||
| ^^^^^^^
|
||||
> 6 | return propA.x();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
> 7 | }, [propA.x]);
|
||||
| ^^^^ CannotPreserveMemoization: React Compiler has skipped optimizing this component because the existing manual memoization could not be preserved. The inferred dependencies did not match the manually specified dependencies, which could cause the value to change more or less frequently than expected (5:7)
|
||||
8 | }
|
||||
9 |
|
||||
```
|
||||
|
||||
|
||||
+6
-1
@@ -19,7 +19,12 @@ function useHook(x) {
|
||||
## Error
|
||||
|
||||
```
|
||||
Todo: Could not preserve manual memoization because an inferred dependency does not match the dependency list in source. The inferred dependency was `x`, but the source dependencies were [aliasedX, aliasedProp]. Detail: inferred different dependency than source
|
||||
7 | const aliasedProp = x.y.z;
|
||||
8 |
|
||||
> 9 | return useMemo(() => [x, x.y.z], [aliasedX, aliasedProp]);
|
||||
| ^^^^^^^^^^^^^^^^ CannotPreserveMemoization: React Compiler has skipped optimizing this component because the existing manual memoization could not be preserved. The inferred dependencies did not match the manually specified dependencies, which could cause the value to change more or less frequently than expected (9:9)
|
||||
10 | }
|
||||
11 |
|
||||
```
|
||||
|
||||
|
||||
+23
-2
@@ -24,9 +24,30 @@ function Component({ propA, propB }) {
|
||||
## Error
|
||||
|
||||
```
|
||||
Todo: Could not preserve manual memoization because an inferred dependency does not match the dependency list in source. The inferred dependency was `propA`, but the source dependencies were [propA.a, propB.x.y]. Detail: inferred less specific property than source
|
||||
4 |
|
||||
5 | function Component({ propA, propB }) {
|
||||
> 6 | return useMemo(() => {
|
||||
| ^^^^^^^
|
||||
> 7 | const x = {};
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
> 8 | if (propA?.a) {
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
> 9 | mutate(x);
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
> 10 | return {
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
> 11 | value: propB.x.y,
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
> 12 | };
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
> 13 | }
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
> 14 | }, [propA?.a, propB.x.y]);
|
||||
| ^^^^ CannotPreserveMemoization: React Compiler has skipped optimizing this component because the existing manual memoization could not be preserved. The inferred dependencies did not match the manually specified dependencies, which could cause the value to change more or less frequently than expected (6:14)
|
||||
|
||||
Todo: Could not preserve manual memoization because an inferred dependency does not match the dependency list in source. The inferred dependency was `propB`, but the source dependencies were [propA.a, propB.x.y]. Detail: inferred less specific property than source
|
||||
CannotPreserveMemoization: React Compiler has skipped optimizing this component because the existing manual memoization could not be preserved. The inferred dependencies did not match the manually specified dependencies, which could cause the value to change more or less frequently than expected (6:14)
|
||||
15 | }
|
||||
16 |
|
||||
```
|
||||
|
||||
|
||||
+23
-2
@@ -24,9 +24,30 @@ function Component({ propA, propB }) {
|
||||
## Error
|
||||
|
||||
```
|
||||
Todo: Could not preserve manual memoization because an inferred dependency does not match the dependency list in source. The inferred dependency was `propA`, but the source dependencies were [propA.a, propB.x.y]. Detail: inferred less specific property than source
|
||||
4 |
|
||||
5 | function Component({ propA, propB }) {
|
||||
> 6 | return useMemo(() => {
|
||||
| ^^^^^^^
|
||||
> 7 | const x = {};
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
> 8 | if (identity(null) ?? propA.a) {
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
> 9 | mutate(x);
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
> 10 | return {
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
> 11 | value: propB.x.y,
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
> 12 | };
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
> 13 | }
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
> 14 | }, [propA.a, propB.x.y]);
|
||||
| ^^^^ CannotPreserveMemoization: React Compiler has skipped optimizing this component because the existing manual memoization could not be preserved. The inferred dependencies did not match the manually specified dependencies, which could cause the value to change more or less frequently than expected (6:14)
|
||||
|
||||
Todo: Could not preserve manual memoization because an inferred dependency does not match the dependency list in source. The inferred dependency was `propB`, but the source dependencies were [propA.a, propB.x.y]. Detail: inferred less specific property than source
|
||||
CannotPreserveMemoization: React Compiler has skipped optimizing this component because the existing manual memoization could not be preserved. The inferred dependencies did not match the manually specified dependencies, which could cause the value to change more or less frequently than expected (6:14)
|
||||
15 | }
|
||||
16 |
|
||||
```
|
||||
|
||||
|
||||
+14
-1
@@ -19,7 +19,20 @@ function Component({ propA }) {
|
||||
## Error
|
||||
|
||||
```
|
||||
Todo: Could not preserve manual memoization because an inferred dependency does not match the dependency list in source. The inferred dependency was `propA`, but the source dependencies were [propA.x]. Detail: inferred less specific property than source
|
||||
3 |
|
||||
4 | function Component({ propA }) {
|
||||
> 5 | return useMemo(() => {
|
||||
| ^^^^^^^
|
||||
> 6 | return {
|
||||
| ^^^^^^^^^^^^
|
||||
> 7 | value: propA.x().y,
|
||||
| ^^^^^^^^^^^^
|
||||
> 8 | };
|
||||
| ^^^^^^^^^^^^
|
||||
> 9 | }, [propA.x]);
|
||||
| ^^^^ CannotPreserveMemoization: React Compiler has skipped optimizing this component because the existing manual memoization could not be preserved. The inferred dependencies did not match the manually specified dependencies, which could cause the value to change more or less frequently than expected (5:9)
|
||||
10 | }
|
||||
11 |
|
||||
```
|
||||
|
||||
|
||||
+10
-1
@@ -17,7 +17,16 @@ function Component({ propA }) {
|
||||
## Error
|
||||
|
||||
```
|
||||
Todo: Could not preserve manual memoization because an inferred dependency does not match the dependency list in source. The inferred dependency was `propA`, but the source dependencies were [propA.x]. Detail: inferred less specific property than source
|
||||
3 |
|
||||
4 | function Component({ propA }) {
|
||||
> 5 | return useMemo(() => {
|
||||
| ^^^^^^^
|
||||
> 6 | return propA.x();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
> 7 | }, [propA.x]);
|
||||
| ^^^^ CannotPreserveMemoization: React Compiler has skipped optimizing this component because the existing manual memoization could not be preserved. The inferred dependencies did not match the manually specified dependencies, which could cause the value to change more or less frequently than expected (5:7)
|
||||
8 | }
|
||||
9 |
|
||||
```
|
||||
|
||||
|
||||
+11
-1
@@ -30,7 +30,17 @@ function useFoo(input1) {
|
||||
## Error
|
||||
|
||||
```
|
||||
Todo: Could not preserve manual memoization because an inferred dependency does not match the dependency list in source. The inferred dependency was `input1`, but the source dependencies were [y]. Detail: inferred different dependency than source
|
||||
14 | const x = {};
|
||||
15 | const y = [input1];
|
||||
> 16 | const memoized = useMemo(() => {
|
||||
| ^^^^^^^
|
||||
> 17 | return [y];
|
||||
| ^^^^^^^^^^^^^^^
|
||||
> 18 | }, [(mutate(x), y)]);
|
||||
| ^^^^ CannotPreserveMemoization: React Compiler has skipped optimizing this component because the existing manual memoization could not be preserved. The inferred dependencies did not match the manually specified dependencies, which could cause the value to change more or less frequently than expected (16:18)
|
||||
19 |
|
||||
20 | return [x, memoized];
|
||||
21 | }
|
||||
```
|
||||
|
||||
|
||||
Reference in New Issue
Block a user