[compiler] Enable optional dependencies by default
Per title. This gives us much more granular memoization when the source used optional member expressions. Note that we only infer optional deps when the source used optionals: we don't (yet) infer optional dependencies from conditionals. ghstack-source-id: 104d0b712d09498239e926e306c4623d546463b1 Pull Request resolved: https://github.com/facebook/react/pull/30838
Joe Savona committed
Aug 28, 2024 at 12:12 UTC
3a45ba241c028cd0af7bf17bb4c6487d0095a10f
7 files changed
+24
-17
compiler/packages/babel-plugin-react-compiler/src/HIR/Environment.ts
+1
-1
@@ -230,7 +230,7 @@ const EnvironmentConfigSchema = z.object({
230
* just `props`. With this flag enabled, we'll infer that full path as
231
* the dependency.
232
*/
233
- enableOptionalDependencies: z.boolean().default(false),
233
+ enableOptionalDependencies: z.boolean().default(true),
234
235
/*
236
* Enable validation of hooks to partially check that the component honors the rules of hooks.
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/optional-call-with-optional-property-load.expect.md
+2
-2
@@ -15,9 +15,9 @@ import { c as _c } from "react/compiler-runtime";
15
function Component(props) {
16
const $ = _c(2);
17
let t0;
18
- if ($[0] !== props) {
18
+ if ($[0] !== props?.items) {
19
t0 = props?.items?.map?.(render)?.filter(Boolean) ?? [];
20
- $[0] = props;
20
+ $[0] = props?.items;
21
$[1] = t0;
22
} else {
23
t0 = $[1];
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.useMemo-infer-less-specific-conditional-access.expect.md
-2
@@ -44,8 +44,6 @@ function Component({propA, propB}) {
44
| ^^^^^^^^^^^^^^^^^
45
> 14 | }, [propA?.a, propB.x.y]);
46
| ^^^^ 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)
47
-
48
-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)
47
15 | }
48
16 |
49
```
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reduce-reactive-deps/conditional-member-expr.expect.md
+2
-2
@@ -29,10 +29,10 @@ import { c as _c } from "react/compiler-runtime"; // To preserve the nullthrows
29
function Component(props) {
30
const $ = _c(2);
31
let x;
32
- if ($[0] !== props.a) {
32
+ if ($[0] !== props.a?.b) {
33
x = [];
34
x.push(props.a?.b);
35
- $[0] = props.a;
35
+ $[0] = props.a?.b;
36
$[1] = x;
37
} else {
38
x = $[1];
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reduce-reactive-deps/memberexpr-join-optional-chain.expect.md
+2
-2
@@ -44,11 +44,11 @@ import { c as _c } from "react/compiler-runtime"; // To preserve the nullthrows
44
function Component(props) {
45
const $ = _c(2);
46
let x;
47
- if ($[0] !== props.a) {
47
+ if ($[0] !== props.a.b) {
48
x = [];
49
x.push(props.a?.b);
50
x.push(props.a.b.c);
51
- $[0] = props.a;
51
+ $[0] = props.a.b;
52
$[1] = x;
53
} else {
54
x = $[1];
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reduce-reactive-deps/memberexpr-join-optional-chain2.expect.md
+15
-6
@@ -21,16 +21,25 @@ export const FIXTURE_ENTRYPOINT = {
21
```javascript
22
import { c as _c } from "react/compiler-runtime";
23
function Component(props) {
24
- const $ = _c(2);
24
+ const $ = _c(5);
25
let x;
26
- if ($[0] !== props.items) {
26
+ if ($[0] !== props.items?.length || $[1] !== props.items?.edges) {
27
x = [];
28
x.push(props.items?.length);
29
- x.push(props.items?.edges?.map?.(render)?.filter?.(Boolean) ?? []);
30
- $[0] = props.items;
31
- $[1] = x;
29
+ let t0;
30
+ if ($[3] !== props.items?.edges) {
31
+ t0 = props.items?.edges?.map?.(render)?.filter?.(Boolean) ?? [];
32
+ $[3] = props.items?.edges;
33
+ $[4] = t0;
34
+ } else {
35
+ t0 = $[4];
36
+ }
37
+ x.push(t0);
38
+ $[0] = props.items?.length;
39
+ $[1] = props.items?.edges;
40
+ $[2] = x;
41
} else {
33
- x = $[1];
42
+ x = $[2];
43
}
44
return x;
45
}
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-scope-missing-mutable-range.expect.md
+2
-2
@@ -23,14 +23,14 @@ function HomeDiscoStoreItemTileRating(props) {
23
const $ = _c(4);
24
const item = useFragment();
25
let count;
26
- if ($[0] !== item) {
26
+ if ($[0] !== item?.aggregates) {
27
count = 0;
28
const aggregates = item?.aggregates || [];
29
aggregates.forEach((aggregate) => {
30
count = count + (aggregate.count || 0);
31
count;
32
});
33
- $[0] = item;
33
+ $[0] = item?.aggregates;
34
$[1] = count;
35
} else {
36
count = $[1];