Skip to content

Conversation

@josephsavona
Copy link
Member

@josephsavona josephsavona commented Jul 29, 2025

We try to merge consecutive reactive scopes that will always invalidate together, but there's one common case that isn't handled.

const y = [[x]];

Here we'll create two consecutive scopes for the inner and outer array expressions. Because the input to the second scope is a temporary, they'll merge into one scope.

But if we name the inner array, the merging stops:

const array = [x];
const y = [array];

This is because the merging logic checks if all the dependencies of the second scope are outputs of the first scope, but doesn't account for renaming due to LoadLocal/StoreLocal. The fix is to track these temporaries.


Stack created with Sapling. Best reviewed with ReviewStack.

@meta-cla meta-cla bot added the CLA Signed label Jul 29, 2025
@github-actions github-actions bot added the React Core Team Opened by a member of the React Core Team label Jul 29, 2025
@react-sizebot
Copy link

react-sizebot commented Jul 29, 2025

Comparing: 88b40f6...4f05dec

Critical size changes

Includes critical production bundles, as well as any change greater than 2%:

Name +/- Base Current +/- gzip Base gzip Current gzip
oss-stable/react-dom/cjs/react-dom.production.js = 6.68 kB 6.68 kB = 1.83 kB 1.83 kB
oss-stable/react-dom/cjs/react-dom-client.production.js = 530.04 kB 530.04 kB = 93.63 kB 93.63 kB
oss-experimental/react-dom/cjs/react-dom.production.js = 6.69 kB 6.69 kB = 1.83 kB 1.83 kB
oss-experimental/react-dom/cjs/react-dom-client.production.js = 654.48 kB 654.48 kB = 115.34 kB 115.34 kB
facebook-www/ReactDOM-prod.classic.js = 674.42 kB 674.42 kB = 118.68 kB 118.68 kB
facebook-www/ReactDOM-prod.modern.js = 664.84 kB 664.84 kB = 117.02 kB 117.02 kB

Significant size changes

Includes any change greater than 0.2%:

Expand to show
Name +/- Base Current +/- gzip Base gzip Current gzip
oss-stable-semver/eslint-plugin-react-hooks/cjs/eslint-plugin-react-hooks.production.js +0.25% 2,068.19 kB 2,073.29 kB +0.12% 298.90 kB 299.24 kB
oss-stable/eslint-plugin-react-hooks/cjs/eslint-plugin-react-hooks.production.js +0.25% 2,068.19 kB 2,073.29 kB +0.12% 298.90 kB 299.24 kB
oss-experimental/eslint-plugin-react-hooks/cjs/eslint-plugin-react-hooks.production.js +0.25% 2,068.37 kB 2,073.47 kB +0.12% 298.92 kB 299.27 kB
oss-stable-semver/eslint-plugin-react-hooks/cjs/eslint-plugin-react-hooks.development.js +0.25% 2,072.67 kB 2,077.76 kB +0.11% 299.91 kB 300.25 kB
oss-stable/eslint-plugin-react-hooks/cjs/eslint-plugin-react-hooks.development.js +0.25% 2,072.67 kB 2,077.76 kB +0.11% 299.91 kB 300.25 kB
oss-experimental/eslint-plugin-react-hooks/cjs/eslint-plugin-react-hooks.development.js +0.25% 2,072.84 kB 2,077.94 kB +0.11% 299.93 kB 300.28 kB

Generated by 🚫 dangerJS against 4f05dec

Fixes remaining issue in #32261, where passing a previously useMemo()-d value to `Object.entries()` makes the compiler think the value is mutated and fail validatePreserveExistingMemo. While I was there I added Object.keys() and Object.values() too.
We try to merge consecutive reactive scopes that will always invalidate together, but there's one common case that isn't handled.

```js
const y = [[x]];
```

Here we'll create two consecutive scopes for the inner and outer array expressions. Because the input to the second scope is a temporary, they'll merge into one scope.

But if we name the inner array, the merging stops:

```js
const array = [x];
const y = [array];
```

This is because the merging logic checks if all the dependencies of the second scope are outputs of the first scope, but doesn't account for renaming due to LoadLocal/StoreLocal. The fix is to track these temporaries.
Copy link
Member

@poteto poteto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fantastic!

josephsavona added a commit that referenced this pull request Aug 1, 2025
Fixes remaining issue in #32261, where passing a previously useMemo()-d
value to `Object.entries()` makes the compiler think the value is
mutated and fail validatePreserveExistingMemo. While I was there I added
Object.keys() and Object.values() too.

---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/34047).
* #34049
* __->__ #34047
* #34044
@josephsavona josephsavona merged commit ddf8bc3 into main Aug 1, 2025
266 of 286 checks passed
github-actions bot pushed a commit that referenced this pull request Aug 1, 2025
Fixes remaining issue in #32261, where passing a previously useMemo()-d
value to `Object.entries()` makes the compiler think the value is
mutated and fail validatePreserveExistingMemo. While I was there I added
Object.keys() and Object.values() too.

---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/34047).
* #34049
* __->__ #34047
* #34044

DiffTrain build for [0860b9c](0860b9c)
github-actions bot pushed a commit that referenced this pull request Aug 1, 2025
Fixes remaining issue in #32261, where passing a previously useMemo()-d
value to `Object.entries()` makes the compiler think the value is
mutated and fail validatePreserveExistingMemo. While I was there I added
Object.keys() and Object.values() too.

---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/34047).
* #34049
* __->__ #34047
* #34044

DiffTrain build for [0860b9c](0860b9c)
github-actions bot pushed a commit that referenced this pull request Aug 1, 2025
We try to merge consecutive reactive scopes that will always invalidate
together, but there's one common case that isn't handled.

```js
const y = [[x]];
```

Here we'll create two consecutive scopes for the inner and outer array
expressions. Because the input to the second scope is a temporary,
they'll merge into one scope.

But if we name the inner array, the merging stops:

```js
const array = [x];
const y = [array];
```

This is because the merging logic checks if all the dependencies of the
second scope are outputs of the first scope, but doesn't account for
renaming due to LoadLocal/StoreLocal. The fix is to track these
temporaries.

---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/34049).
* __->__ #34049
* #34047
* #34044

DiffTrain build for [ddf8bc3](ddf8bc3)
github-actions bot pushed a commit to code/lib-react that referenced this pull request Aug 3, 2025
…ok#34049)

We try to merge consecutive reactive scopes that will always invalidate
together, but there's one common case that isn't handled.

```js
const y = [[x]];
```

Here we'll create two consecutive scopes for the inner and outer array
expressions. Because the input to the second scope is a temporary,
they'll merge into one scope.

But if we name the inner array, the merging stops:

```js
const array = [x];
const y = [array];
```

This is because the merging logic checks if all the dependencies of the
second scope are outputs of the first scope, but doesn't account for
renaming due to LoadLocal/StoreLocal. The fix is to track these
temporaries.

---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/34049).
* __->__ facebook#34049
* facebook#34047
* facebook#34044

DiffTrain build for [ddf8bc3](facebook@ddf8bc3)
github-actions bot pushed a commit to code/lib-react that referenced this pull request Aug 3, 2025
…ok#34049)

We try to merge consecutive reactive scopes that will always invalidate
together, but there's one common case that isn't handled.

```js
const y = [[x]];
```

Here we'll create two consecutive scopes for the inner and outer array
expressions. Because the input to the second scope is a temporary,
they'll merge into one scope.

But if we name the inner array, the merging stops:

```js
const array = [x];
const y = [array];
```

This is because the merging logic checks if all the dependencies of the
second scope are outputs of the first scope, but doesn't account for
renaming due to LoadLocal/StoreLocal. The fix is to track these
temporaries.

---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/34049).
* __->__ facebook#34049
* facebook#34047
* facebook#34044

DiffTrain build for [ddf8bc3](facebook@ddf8bc3)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed React Core Team Opened by a member of the React Core Team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants