Upgrade compiler playground to use the newest nextjs release, which
includes react compiler transform pipeline optimizations
https://github.com/vercel/next.js/pull/75676/.
Also made a drive-by fix to avoid the error `Cannot update a component
('Router') while rendering a different component ('StoreProvider'). To
locate the bad setState() call inside 'StoreProvider', follow the stack
trace as described in https://react.dev/link/setstate-in-render`. The
bad setState came from `history.replaceState({}, '', \`#${hash}\`);`.
Prior to this, playground ran side effects in a reducer (i.e. during
render). These have now been moved an effect.
Update eslint-plugin-react-hooks to be built targetting ES5 instead. For
various reasons our internal infra relies on these files being built
already downleveled.
Test fixtures testing different compiler features (e.g. non-auto
memoization) should live in separate directories.
Remove bug-prefixed fixtures that have since been fixed
Add test evaluator export to more fixtures
Prior to this PR, our HIR represented property access with numeric
literals (e.g. `myVar[0]`) as ComputedLoads. This means that they were
subject to some deopts (most notably, not being easily dedupable /
hoistable as dependencies).
Now, `PropertyLoad`, `PropertyStore`, etc reference numeric and string
literals (although not yet string literals that aren't valid babel
identifiers). The difference between PropertyLoad and ComputedLoad is
fuzzy now (maybe we should rename these).
- PropertyLoad: property keys are string and numeric literals, only when
the string literals are valid babel identifiers
- ComputedLoad: non-valid babel identifier string literals (rare) and
other non-literal expressions
The biggest feature from this PR is that it trivially enables
array-indicing expressions as dependencies. The compiler can also
specify global and imported types for arrays (e.g. return value of
`useState`)
I'm happy to close this if it complicates more than it helps --
alternative options are to entirely rely on instruction reordering-based
approaches like ReactiveGraphIR or make dependency-specific parsing +
hoisting logic more robust.
LoweredFunction dependencies were exclusively used for dependency
extraction (in `propagateScopeDeps`). Now that we have a
`propagateScopeDepsHIR` that recursively traverses into nested
functions, we can delete `dependencies` and their associated synthetic
`LoadLocal`/`PropertyLoad` instructions.
[Internal snapshot
diff](https://www.internalfb.com/phabricator/paste/view/P1716950202) for
this change shows ~.2% of files changed. I [read through ~60 of the
changed
files](https://www.internalfb.com/phabricator/paste/view/P1733074307)
- most changes are due to better outlining (due to better DCE)
- a few changes in memo inference are due to changed ordering
```
// source
arr.map(() => contextVar.inner);
// previous instructions
$0 = LoadLocal arr
$1 = $0.map
// Below instructions are synthetic
$2 = LoadLocal contextVar
$3 = $2.inner
$4 = Function deps=$3 context=contextVar {
...
}
```
- a few changes are effectively bugfixes (see
`aliased-nested-scope-fn-expr`)
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32096).
* #32099
* #32286
* #32104
* #32098
* #32097
* __->__ #32096
This change removes the `devEngines` declaration in the root package. It
didn't match the package.json spec and in npm 10.9.0 (released in
October), a breaking change was introduced that checks the `devEngines`
property. This causes `npm pack` calls to fail, due to the malformed
`devEngines`. Since there's already an `.nvmrc` defined in the repo, and
no strong need to enforce a specific node version for local development,
this removes the declaration altogether.
## Summary
The `flow-api-translator` from the `hermes` repo does not support flow
type spreads. It is currently not able to digest the ReactNativeTypes
file as it contains unsupported syntax. The simplest solution is to
change the type of the `TouchedViewDataAtPoint` to equivalent, yet
supported by the Flow tooling. In this case the intersection can be used
as
the `TouchedViewDataAtPoint` and `InspectorData` have no common
property.
## How did you test this change?
Run yarn flow native
This Hook will be used to drive a View Transition based on a gesture.
```js
const [value, startGesture] = useSwipeTransition(prev, current, next);
```
The `enableSwipeTransition` flag will depend on `enableViewTransition`
flag but we may decide to ship them independently. This PR doesn't do
anything interesting yet. There will be a lot more PRs to build out the
actual functionality. This is just wiring up the plumbing for the new
Hook.
This first PR is mainly concerned with how the whole starts (and stops).
The core API is the `startGesture` function (although there will be
other conveniences added in the future). You can call this to start a
gesture with a source provider. You can call this multiple times in one
event to batch multiple Hooks listening to the same provider. However,
each render can only handle one source provider at a time and so it does
one render per scheduled gesture provider.
This uses a separate `GestureLane` to drive gesture renders by marking
the Hook as having an update on that lane. Then schedule a render. These
renders should be blocking and in the same microtask as the
`startGesture` to ensure it can block the paint. So it's similar to
sync.
It may not be possible to finish it synchronously e.g. if something
suspends. If so, it just tries again later when it can like any other
render. This can also happen because it also may not be possible to
drive more than one gesture at a time like if we're limited to one View
Transition per document. So right now you can only run one gesture at a
time in practice.
These renders never commit. This means that we can't clear the
`GestureLane` the normal way. Instead, we have to clear only the root's
`pendingLanes` if we don't have any new renders scheduled. Then wait
until something else updates the Fiber after all gestures on it have
stopped before it really clears.
For Hookstate Proxies of class instances, `data.constructor.name`
returns `Proxy({})`, so use
`Object.getPrototypeOf(data).constructor.name` instead, which works
correctly from my testing.
<!--
Thanks for submitting a pull request!
We appreciate you spending the time to work on these changes. Please
provide enough information so that others can review your pull request.
The three fields below are mandatory.
Before submitting a pull request, please make sure the following is
done:
1. Fork [the repository](https://github.com/facebook/react) and create
your branch from `main`.
2. Run `yarn` in the repository root.
3. If you've fixed a bug or added code that should be tested, add tests!
4. Ensure the test suite passes (`yarn test`). Tip: `yarn test --watch
TestName` is helpful in development.
5. Run `yarn test --prod` to test in the production environment. It
supports the same options as `yarn test`.
6. If you need a debugger, run `yarn test --debug --watch TestName`,
open `chrome://inspect`, and press "Inspect".
7. Format your code with
[prettier](https://github.com/prettier/prettier) (`yarn prettier`).
8. Make sure your code lints (`yarn lint`). Tip: `yarn linc` to only
check changed files.
9. Run the [Flow](https://flowtype.org/) type checks (`yarn flow`).
10. If you haven't already, complete the CLA.
Learn more about contributing:
https://reactjs.org/docs/how-to-contribute.html
-->
## Summary
React DevTools immediately bricks itself if you inspect any component
that has a prop that is a Hookstate that wraps a class instance ...
because these are proxies where `data.constructor.name` returns some
un-cloneable object, but `Object.getPrototypeOf(data)` doesn't return
`Object` (it returns the prototype of the class inside).
## How did you test this change?
This part of the code has no associated tests at all.
Technically,
`packages/react-devtools-shared/src/__tests__/legacy/inspectElement-test.js`
exists, but I tried `yarn test` and these tests aren't even executed
anymore. I can't figure it out, so whatever.
If you run this code:
```js
class Class {}
const instance = new Class();
const instanceProxy = new Proxy(instance, {
get(target, key, receiver) {
if (key === 'constructor') {
return { name: new Proxy({}, {}) };
}
return Reflect.get(target, key, receiver);
},
});
```
then `instanceProxy.constructor.name` returns some proxy that cannot be
cloned, but `Object.getPrototypeOf(instanceProxy).constructor.name`
returns the correct value.
This PR fixes the devtools to use
`Object.getPrototypeOf(instanceProxy).constructor.name`.
I modified my local copy of devtools to use this method and it fixed the
bricking that I experienced.
Related #29954
<!--
Thanks for submitting a pull request!
We appreciate you spending the time to work on these changes. Please
provide enough information so that others can review your pull request.
The three fields below are mandatory.
Before submitting a pull request, please make sure the following is
done:
1. Fork [the repository](https://github.com/facebook/react) and create
your branch from `main`.
2. Run `yarn` in the repository root.
3. If you've fixed a bug or added code that should be tested, add tests!
4. Ensure the test suite passes (`yarn test`). Tip: `yarn test --watch
TestName` is helpful in development.
5. Run `yarn test --prod` to test in the production environment. It
supports the same options as `yarn test`.
6. If you need a debugger, run `yarn test --debug --watch TestName`,
open `chrome://inspect`, and press "Inspect".
7. Format your code with
[prettier](https://github.com/prettier/prettier) (`yarn prettier`).
8. Make sure your code lints (`yarn lint`). Tip: `yarn linc` to only
check changed files.
9. Run the [Flow](https://flowtype.org/) type checks (`yarn flow`).
10. If you haven't already, complete the CLA.
Learn more about contributing:
https://reactjs.org/docs/how-to-contribute.html
-->
## Summary
<!--
Explain the **motivation** for making this change. What existing problem
does the pull request solve?
-->
When using React Devtools, calling `console.log('%s', null)` in userland
can cause it to throw an error:
```
TypeError: Cannot read properties of null (reading 'toString')
```
## How did you test this change?
Added a unit test.
<!--
Demonstrate the code is solid. Example: The exact commands you ran and
their output, screenshots / videos if the pull request changes the user
interface.
How exactly did you verify that your PR solves the issue you wanted to
solve?
If you leave this empty, your PR will very likely be closed.
-->
See https://github.com/47ng/nuqs/issues/808.
## Summary
In React Native, public instances and internal host nodes are not
represented by the same object (ReactNativeElement & shadow nodes vs.
just DOM elements), and the only one that's required for rendering is
the shadow node. Public instances are generally only necessary when
accessed via refs or events, and that usually happens for a small amount
of components in the tree.
This implements an optimization to create the public instance on demand,
instead of eagerly creating it when creating the host node. We expect
this to improve performance by reducing the logic we do per node and the
number of object allocations.
## How did you test this change?
Manually synced the changes to React Native and run Fantom tests and
benchmarks, with the flag enabled and disabled. All tests pass in both
cases, and benchmarks show a slight but consistent performance
improvement.
## Summary
Fixes#32354.
Re-creation of #15197: adds a dev-only warning if `create == null` to
the three `use*Effect` functions:
* `useEffect`
* `useInsertionEffect`
* `useLayoutEffect`
Updates the warning to match the same text given in the
`react/exhaustive-deps` lint rule.
## How did you test this change?
I applied the changes manually within `node_modules/` on a local clone
of
https://github.com/JoshuaKGoldberg/repros/tree/react-use-effect-no-arguments.
Please pardon me for opening a PR addressing a not-accepted issue. I was
excited to get back to #15194 -> #15197 now that I have time. 🙂
---------
Co-authored-by: lauren <poteto@users.noreply.github.com>
Merges the useResourceEffect API into useEffect while keeping the
underlying implementation the same. useResourceEffect will be removed in
the next diff.
To fork between behavior we rely on a `typeof` check for the updater or
destroy function in addition to the CRUD feature flag. This does now
have to be checked every time (instead of inlined statically like before
due to them being different hooks) which will incur some non-zero amount
(possibly negligble) of overhead for every effect.
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32205).
* #32206
* __->__ #32205
Small refactor to the `resource` type to narrow it to an arbitrary
object or void/null instead of the top type. This makes the overload on
useEffect simpler since the return type of create is no longer widened
to the top type when we merge their definitions.
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32203).
* #32206
* #32205
* #32204
* __->__ #32203
## Summary
This PR attempts to make running the React DevTools a little friendlier
in projects that are not completely React.
At the moment, running the DevTools with `npx react-devtools` will
default to the port to use the `PORT` env variable otherwise it'll fall
back to `8097`. `PORT` is a common env variable, so we can get into this
strange situation where the a Rails server (eg Puma) is using `PORT`,
and then the React DevTools attempts to boot using the same `PORT`.
This PR introduces a dedicated env variable, `REACT_DEVTOOLS_PORT` to
assist in this scenario.
## How did you test this change?
I'm using fish shell, so I did the following, please let me know if
there's a better way:
```sh
cd packages/react-devtools
set -x PORT 1000
set -x REACT_DEVTOOLS_PORT 2000
node bin.js
```
We can see in the UI that it's listening on `2000`. Without this PR,
it'd listen on `1000`:

Follow-up for #32332. The Discord webhook seems to ignore draft PRs,
which is a good thing. But when a draft PR is then later set to "ready
for review" we do want to send another notification that should not be
filtered out.
Our internal build infra relies on a 1:1 mapping between `main` and the
2 build branches. Directly committing changes to those branches breaks
that infra.
Adds a simple workflow to leave a comment and decline the PR.
There's no real reason to have 2 jobs for sizebot. It's more of a
historical artifact from before the GH migration. Merging them should
require one less worker needing to be provisioned and some of the extra
overhead
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32333).
* __->__ #32333
* #32332
Adds a new Timing logger event to the compiler which currently only
records the walltime of running the compiler from the time the babel
plugin's Program visitor enters to the time it exits.
To enable, run the compiler with `ENABLE_REACT_COMPILER_TIMINGS=1 ...`
or `export ENABLE_REACT_COMPILER_TIMINGS=1` to set it by default.
<!--
Thanks for submitting a pull request!
We appreciate you spending the time to work on these changes. Please
provide enough information so that others can review your pull request.
The three fields below are mandatory.
Before submitting a pull request, please make sure the following is
done:
1. Fork [the repository](https://github.com/facebook/react) and create
your branch from `main`.
2. Run `yarn` in the repository root.
3. If you've fixed a bug or added code that should be tested, add tests!
4. Ensure the test suite passes (`yarn test`). Tip: `yarn test --watch
TestName` is helpful in development.
5. Run `yarn test --prod` to test in the production environment. It
supports the same options as `yarn test`.
6. If you need a debugger, run `yarn test --debug --watch TestName`,
open `chrome://inspect`, and press "Inspect".
7. Format your code with
[prettier](https://github.com/prettier/prettier) (`yarn prettier`).
8. Make sure your code lints (`yarn lint`). Tip: `yarn linc` to only
check changed files.
9. Run the [Flow](https://flowtype.org/) type checks (`yarn flow`).
10. If you haven't already, complete the CLA.
Learn more about contributing:
https://reactjs.org/docs/how-to-contribute.html
-->
## Summary
<!--
Explain the **motivation** for making this change. What existing problem
does the pull request solve?
-->
Improve the error message, as the value is currently an object instead
of a string, which results in it being converted to '[object Object]'.
## How did you test this change?
Already tested locally.
<!--
Demonstrate the code is solid. Example: The exact commands you ran and
their output, screenshots / videos if the pull request changes the user
interface.
How exactly did you verify that your PR solves the issue you wanted to
solve?
If you leave this empty, your PR will very likely be closed.
-->
followup to
* https://github.com/facebook/react/pull/32069
* https://github.com/facebook/react/pull/32163
* https://github.com/facebook/react/pull/32224
in react-dom in Dev we validate that the tag nesting is valid. This is
motivated primarily because while browsers are tolerant to poor HTML
there are many cases that if server rendered will be hydrated in a way
that will break hydration.
With the changes to singleton scoping where the document body is now the
implicit render/hydration context for arbitrary tags at the root we need
to adjust the validation logic to allow for valid programs such as
rendering divs as a child of a Document (since this div will actually
insert into the body).
While modern DOM implementations all support getRootNode if you are
running React in a runtime which does not the fallback logic which uses
`.ownerDocument` works everywhere except when the container is a
Document itself. This change corrects this by returning the container
intsance if it is a Document type.