[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: 104d0b712d
Pull Request resolved: https://github.com/facebook/react/pull/30838
This commit is contained in:
Joe Savona
2024-08-28 15:59:26 -07:00
parent 99a4b26e18
commit 3a45ba241c
7 changed files with 24 additions and 17 deletions
@@ -230,7 +230,7 @@ const EnvironmentConfigSchema = z.object({
* just `props`. With this flag enabled, we'll infer that full path as
* the dependency.
*/
enableOptionalDependencies: z.boolean().default(false),
enableOptionalDependencies: z.boolean().default(true),
/*
* Enable validation of hooks to partially check that the component honors the rules of hooks.
@@ -15,9 +15,9 @@ import { c as _c } from "react/compiler-runtime";
function Component(props) {
const $ = _c(2);
let t0;
if ($[0] !== props) {
if ($[0] !== props?.items) {
t0 = props?.items?.map?.(render)?.filter(Boolean) ?? [];
$[0] = props;
$[0] = props?.items;
$[1] = t0;
} else {
t0 = $[1];
@@ -44,8 +44,6 @@ function Component({propA, propB}) {
| ^^^^^^^^^^^^^^^^^
> 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)
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 |
```
@@ -29,10 +29,10 @@ import { c as _c } from "react/compiler-runtime"; // To preserve the nullthrows
function Component(props) {
const $ = _c(2);
let x;
if ($[0] !== props.a) {
if ($[0] !== props.a?.b) {
x = [];
x.push(props.a?.b);
$[0] = props.a;
$[0] = props.a?.b;
$[1] = x;
} else {
x = $[1];
@@ -44,11 +44,11 @@ import { c as _c } from "react/compiler-runtime"; // To preserve the nullthrows
function Component(props) {
const $ = _c(2);
let x;
if ($[0] !== props.a) {
if ($[0] !== props.a.b) {
x = [];
x.push(props.a?.b);
x.push(props.a.b.c);
$[0] = props.a;
$[0] = props.a.b;
$[1] = x;
} else {
x = $[1];
@@ -21,16 +21,25 @@ export const FIXTURE_ENTRYPOINT = {
```javascript
import { c as _c } from "react/compiler-runtime";
function Component(props) {
const $ = _c(2);
const $ = _c(5);
let x;
if ($[0] !== props.items) {
if ($[0] !== props.items?.length || $[1] !== props.items?.edges) {
x = [];
x.push(props.items?.length);
x.push(props.items?.edges?.map?.(render)?.filter?.(Boolean) ?? []);
$[0] = props.items;
$[1] = x;
let t0;
if ($[3] !== props.items?.edges) {
t0 = props.items?.edges?.map?.(render)?.filter?.(Boolean) ?? [];
$[3] = props.items?.edges;
$[4] = t0;
} else {
t0 = $[4];
}
x.push(t0);
$[0] = props.items?.length;
$[1] = props.items?.edges;
$[2] = x;
} else {
x = $[1];
x = $[2];
}
return x;
}
@@ -23,14 +23,14 @@ function HomeDiscoStoreItemTileRating(props) {
const $ = _c(4);
const item = useFragment();
let count;
if ($[0] !== item) {
if ($[0] !== item?.aggregates) {
count = 0;
const aggregates = item?.aggregates || [];
aggregates.forEach((aggregate) => {
count = count + (aggregate.count || 0);
count;
});
$[0] = item;
$[0] = item?.aggregates;
$[1] = count;
} else {
count = $[1];