Commit Graph
672 Commits
Author SHA1 Message Date
acdlite fb3bede17d Support writing to this.refs from userspace (#28867)
Previously, the `refs` property of a class component instance was
read-only by user code — only React could write to it, and until/unless
a string ref was used, it pointed to a shared empty object that was
frozen in dev to prevent userspace mutations.

Because string refs are deprecated, we want users to be able to codemod
all their string refs to callback refs. The safest way to do this is to
output a callback ref that assigns to `this.refs`.

So to support this, we need to make `this.refs` writable by userspace.

DiffTrain build for [ea24427d16](https://github.com/facebook/react/commit/ea24427d16f3ac9b0f3bb45cdc7919ac208130c9)
2024-04-18 17:42:33 +00:00
gnoff e69bce2f06 [UMD] Remove umd builds (#28735)
In React 19 React will finally stop publishing UMD builds. This is
motivated primarily by the lack of use of UMD format and the added
complexity of maintaining build infra for these releases. Additionally
with ESM becoming more prevalent in browsers and services like esm.sh
which can host React as an ESM module there are other options for doing
script tag based react loading.

This PR removes all the UMD build configs and forks.

There are some fixtures that still have references to UMD builds however
many of them already do not work (for instance they are using legacy
features like ReactDOM.render) and rather than block the removal on
these fixtures being brought up to date we'll just move forward and fix
or removes fixtures as necessary in the future.

DiffTrain build for [da6ba53b10](https://github.com/facebook/react/commit/da6ba53b10d8240fc251ba14a3e5878604d3dc7d)
2024-04-17 18:20:36 +00:00
sebmarkbage 656e0f4997 Test top level fragment inside lazy semantics (#28852)
This wasn't clearly articulated and tested why the code structure is
like this but I think the logic is correct - or at least consistent with
the weird semantics.

We place this top-level fragment check inside the recursion so that you
can resolve how many every Lazy or Usable wrappers you want and it still
preserves the same semantics if they weren't there (which they might not
be as a matter of a race condition).

However, we don't actually recurse with the top-level fragment
unwrapping itself because nesting a bunch of keyless fragments isn't the
same as a single fragment/element.

DiffTrain build for [4ca20fd36b](https://github.com/facebook/react/commit/4ca20fd36b2444a74279e7022f89894710b1daab)
2024-04-17 16:43:50 +00:00
sebmarkbage 1db2e35f8e Promote ASYNC_ITERATOR symbol to React Symbols (#28851)
So that when we end up referring to it in more places, it's only one.

We don't do this same pattern for regular `Symbol.iterator` because we
also support the string `"@@iterator"` for backwards compatibility.

DiffTrain build for [c0cf7c696c](https://github.com/facebook/react/commit/c0cf7c696cf454b49b35d8dae01ab111739dab46)
2024-04-17 16:34:09 +00:00
sebmarkbage 9080248d2e [Flight] Encode ReadableStream and AsyncIterables (#28847)
This adds support in Flight for serializing four kinds of streams:

- `ReadableStream` with objects as a model. This is a single shot
iterator so you can read it only once. It can contain any value
including Server Components. Chunks are encoded as is so if you send in
10 typed arrays, you get the same typed arrays out on the other side.
- Binary `ReadableStream` with `type: 'bytes'` option. This supports the
BYOB protocol. In this mode, the receiving side just gets `Uint8Array`s
and they can be split across any single byte boundary into arbitrary
chunks.
- `AsyncIterable` where the `AsyncIterator` function is different than
the `AsyncIterable` itself. In this case we assume that this might be a
multi-shot iterable and so we buffer its value and you can iterate it
multiple times on the other side. We support the `return` value as a
value in the single completion slot, but you can't pass values in
`next()`. If you want single-shot, return the AsyncIterator instead.
- `AsyncIterator`. These gets serialized as a single-shot as it's just
an iterator.

`AsyncIterable`/`AsyncIterator` yield Promises that are instrumented
with our `.status`/`.value` convention so that they can be synchronously
looped over if available. They are also lazily parsed upon read.

We can't do this with `ReadableStream` because we use the native
implementation of `ReadableStream` which owns the promises.

The format is a leading row that indicates which type of stream it is.
Then a new row with the same ID is emitted for every chunk. Followed by
either an error or close row.

`AsyncIterable`s can also be returned as children of Server Components
and then they're conceptually the same as fragment arrays/iterables.
They can't actually be used as children in Fizz/Fiber but there's a
separate plan for that. Only `AsyncIterable` not `AsyncIterator` will be
valid as children - just like sync `Iterable` is already supported but
single-shot `Iterator` is not. Notably, neither of these streams
represent updates over time to a value. They represent multiple values
in a list.

When the server stream is aborted we also close the underlying stream.
However, closing a stream on the client, doesn't close the underlying
stream.

A couple of possible follow ups I'm not planning on doing right now:

- [ ] Free memory by releasing the buffer if an Iterator has been
exhausted. Single shots could be optimized further to release individual
items as you go.
- [ ] We could clean up the underlying stream if the only pending data
that's still flowing is from streams and all the streams have cleaned
up. It's not very reliable though. It's better to do cancellation for
the whole stream - e.g. at the framework level.
- [ ] Implement smarter Binary Stream chunk handling. Currently we wait
until we've received a whole row for binary chunks and copy them into
consecutive memory. We need this to preserve semantics when passing
typed arrays. However, for binary streams we don't need that. We can
just send whatever pieces we have so far.

DiffTrain build for [7909d8eabb](https://github.com/facebook/react/commit/7909d8eabb7a702618f51e16a351df41aa8da88e)
2024-04-16 16:25:08 +00:00
kassens 34d4293051 Remove redundant props assign (#28829)
DiffTrain build for [9defcd56bc](https://github.com/facebook/react/commit/9defcd56bc3cd53ac2901ed93f29218007010434)
2024-04-15 15:58:37 +00:00
kassens 5f5d13f66b Fix mistaken "react-server" condition (#28835)
This is a Fizz server.

DiffTrain build for [ed40236036](https://github.com/facebook/react/commit/ed4023603632787db6416bee8e85e68d98ad29bd)
2024-04-15 15:53:42 +00:00
kassens 83a7b455d4 [Fizz] hoistables should never flush before the preamble (#28802)
Hoistables should never flush before the preamble however there is a
surprisingly easy way to trigger this to happen by suspending in the
shell of the app. This change modifies the flushing behavior to not emit
any hoistables before the preamble has written. It accomplishes this by
aborting the flush early if there are any pending root tasks remaining.
It's unfortunate we need this extra condition but it's essential that we
don't emit anything before the preamble and at the moment I don't see a
way to do that without introducing a new condition.

There is a test that began to fail with this update. It turns out that
in node the root can be blocked during a resume even for a component
inside a Suspense boundary if that boundary was part of the prerender.
This means that with the current heuristic in this PR boundaries cannot
be flushed during resume until the root is unblocked. This is not ideal
but this is already how Edge works because the root blocks the stream in
that case. This just makes Node deopt in a similar way to edge. We
should improve this but we ought to do so in a way that works for edge
too and it needs to be more comprehensive.

DiffTrain build for [c8a035036d](https://github.com/facebook/react/commit/c8a035036d0f257c514b3628e927dd9dd26e5a09)
2024-04-15 15:30:16 +00:00
kassens 5735300a0c DevTools: Rely on sourcemaps to compute hook name of built-in hooks in newer versions (#28593)
DiffTrain build for [4f5c812a3c](https://github.com/facebook/react/commit/4f5c812a3c4e52d9ea5d908a27a317ac0f26590a)
2024-04-15 15:02:04 +00:00
eps1lon baf3dfbb22 Remove redundant props assign (#28829)
DiffTrain build for [9defcd56bc](https://github.com/facebook/react/commit/9defcd56bc3cd53ac2901ed93f29218007010434)
2024-04-12 20:00:32 +00:00
kassens 2377985dee Fix mistaken "react-server" condition (#28835)
This is a Fizz server.

DiffTrain build for [ed40236036](https://github.com/facebook/react/commit/ed4023603632787db6416bee8e85e68d98ad29bd)
2024-04-12 19:58:45 +00:00
kassens a4c720b9e4 Remove defaultProps support (except for classes) (#28733)
This removes defaultProps support for all component types except for
classes. We've chosen to continue supporting defaultProps for classes
because lots of older code relies on it, and unlike function components,
(which can use default params), there's no straightforward alternative.

By implication, it also removes support for setting defaultProps on
`React.lazy` wrapper. So this will not work:

```js
const MyClassComponent = React.lazy(() => import('./MyClassComponent'));
// MyClassComponent is not actually a class; it's a lazy wrapper. So
// defaultProps does not work.
MyClassComponent.defaultProps = { foo: 'bar' };
```

However, if you set the default props on the class itself, then it's
fine.

For classes, this change also moves where defaultProps are resolved.
Previously, defaultProps were resolved by the JSX runtime. This change
is only observable if you introspect a JSX element, which is relatively
rare but does happen.

In other words, previously `<ClassWithDefaultProp />.props.aDefaultProp`
would resolve to the default prop value, but now it does not.

DiffTrain build for [48b4ecc901](https://github.com/facebook/react/commit/48b4ecc9012638ed51b275aad24b2086b8215e32)
2024-04-11 21:29:14 +00:00
kassens 2f685cbcac [Flight] Support Blobs from Server to Client (#28755)
We currently support Blobs when passing from Client to Server so this
adds it in the other direction for parity - when `enableFlightBinary` is
enabled.

We intentionally only support the `Blob` type to pass-through, not
subtype `File`. That's because passing additional meta data like
filename might be an accidental leak. You can still pass a `File`
through but it'll appear as a `Blob` on the other side. It's also not
possible to create a faithful File subclass in all environments without
it actually being backed by a file.

This implementation isn't great but at least it works. It creates a few
indirections. This is because we need to be able to asynchronously emit
the buffers but we have to "block" the parent object from resolving
while it's loading.

Ideally, we should be able to create the Blob on the client early and
then stream in it lazily. Because the Blob API doesn't guarantee that
the data is available synchronously. Unfortunately, the native APIs
doesn't have this. We could implement custom versions of all the data
read APIs but then the blobs still wouldn't work with native APIs. So we
just have to wait until Blob accepts a stream in the constructor.

We should be able to stream each chunk early in the protocol though even
though we can't unblock the parent until they've all loaded. I didn't do
this yet mostly because of code structure and I'm lazy.

DiffTrain build for [c0b5d435986e7d9b52a529b73b9317a7e5772172](https://github.com/facebook/react/commit/c0b5d435986e7d9b52a529b73b9317a7e5772172)
2024-04-11 19:21:35 +00:00
kassens d9f3448f11 Revert "Track Owner for Server Components in DEV (#28753)"
This reverts commit e0455fe62a648f541d2e029017465ae4b5f000a8.

DiffTrain build for [87b495f7d26a2c631c08952661d38bb5ce5acb03](https://github.com/facebook/react/commit/87b495f7d26a2c631c08952661d38bb5ce5acb03)
2024-04-11 19:03:10 +00:00
kassens 2b619ee8b7 Track Owner for Server Components in DEV (#28753)
This implements the concept of a DEV-only "owner" for Server Components.
The owner concept isn't really super useful. We barely use it anymore,
but we do have it as a concept in DevTools in a couple of cases so this
adds it for parity. However, this is mainly interesting because it could
be used to wire up future owner-based stacks.

I do this by outlining the DebugInfo for a Server Component
(ReactComponentInfo). Then I just rely on Flight deduping to refer to
that. I refer to the same thing by referential equality so that we can
associate a Server Component parent in DebugInfo with an owner.

If you suspend and replay a Server Component, we have to restore the
same owner. To do that, I did a little ugly hack and stashed it on the
thenable state object. Felt unnecessarily complicated to add a stateful
wrapper for this one dev-only case.

The owner could really be anything since it could be coming from a
different implementation. Because this is the first time we have an
owner other than Fiber, I have to fix up a bunch of places that assumes
Fiber. I mainly did the `typeof owner.tag === 'number'` to assume it's a
Fiber for now.

This also doesn't actually add it to DevTools / RN Inspector yet. I just
ignore them there for now.

Because Server Components can be async the owner isn't tracked after an
await. We need per-component AsyncLocalStorage for that. This can be
done in a follow up.

DiffTrain build for [e0455fe62a648f541d2e029017465ae4b5f000a8](https://github.com/facebook/react/commit/e0455fe62a648f541d2e029017465ae4b5f000a8)
2024-04-11 18:48:05 +00:00
kassens 60928e358c Remove defaultProps support (except for classes) (#28733)
This removes defaultProps support for all component types except for
classes. We've chosen to continue supporting defaultProps for classes
because lots of older code relies on it, and unlike function components,
(which can use default params), there's no straightforward alternative.

By implication, it also removes support for setting defaultProps on
`React.lazy` wrapper. So this will not work:

```js
const MyClassComponent = React.lazy(() => import('./MyClassComponent'));
// MyClassComponent is not actually a class; it's a lazy wrapper. So
// defaultProps does not work.
MyClassComponent.defaultProps = { foo: 'bar' };
```

However, if you set the default props on the class itself, then it's
fine.

For classes, this change also moves where defaultProps are resolved.
Previously, defaultProps were resolved by the JSX runtime. This change
is only observable if you introspect a JSX element, which is relatively
rare but does happen.

In other words, previously `<ClassWithDefaultProp />.props.aDefaultProp`
would resolve to the default prop value, but now it does not.

DiffTrain build for [48b4ecc901](https://github.com/facebook/react/commit/48b4ecc9012638ed51b275aad24b2086b8215e32)
2024-04-11 18:03:18 +00:00
acdlite e45e8f386b ReactDOM.requestFormReset (#28809)
Based on:

- #28808
- #28804

---

This adds a React DOM method called requestFormReset that schedules a
form reset to occur when the current transition completes.

Internally, it's the same method that's called automatically whenever a
form action is submitted. It only affects uncontrolled form inputs. See
https://github.com/facebook/react/pull/28804 for details.

The reason for the public API is so UI libraries can implement their own
action-based APIs and maintain the form-resetting behavior, something
like this:

```js
function onSubmit(event) {
  // Disable default form submission behavior
  event.preventDefault();
  const form = event.target;
  startTransition(async () => {
    // Request the form to reset once the action
    // has completed
    requestFormReset(form);

    // Call the user-provided action prop
    await action(new FormData(form));
  })
}
```

DiffTrain build for [da69b6af96](https://github.com/facebook/react/commit/da69b6af9697b8042834644b14d0e715d4ace18a)
2024-04-10 21:01:38 +00:00
acdlite 52ba1cb9a9 Scaffolding for requestFormReset API (#28808)
Based on:

- #28804

---

This sets adds a new ReactDOM export called requestFormReset, including
setting up the export and creating a method on the internal ReactDOM
dispatcher. It does not yet add any implementation.

Doing this in its own commit for review purposes.

The API itself will be explained in the next PR.

DiffTrain build for [374b5d26c2](https://github.com/facebook/react/commit/374b5d26c2a379fe87ee6817217c8956c4e39aac)
2024-04-10 20:59:58 +00:00
acdlite 6d6562ec23 Automatically reset forms after action finishes (#28804)
This updates the behavior of form actions to automatically reset the
form's uncontrolled inputs after the action finishes.

This is a frequent feature request for people using actions and it
aligns the behavior of client-side form submissions more closely with
MPA form submissions.

It has no impact on controlled form inputs. It's the same as if you
called `form.reset()` manually, except React handles the timing of when
the reset happens, which is tricky/impossible to get exactly right in
userspace.

The reset shouldn't happen until the UI has updated with the result of
the action. So, resetting inside the action is too early.

Resetting in `useEffect` is better, but it's later than ideal because
any effects that run before it will observe the state of the form before
it's been reset.

It needs to happen in the mutation phase of the transition. More
specifically, after all the DOM mutations caused by the transition have
been applied. That way the `defaultValue` of the inputs are updated
before the values are reset. The idea is that the `defaultValue`
represents the current, canonical value sent by the server.

Note: this change has no effect on form submissions that aren't
triggered by an action.

DiffTrain build for [41950d14a5](https://github.com/facebook/react/commit/41950d14a538aa7411b00b28bcd94ae95a45976e)
2024-04-10 20:59:21 +00:00
gnoff 05f6de56f4 [Float] Don't preload images inside <noscript> (#28815)
`<noscript>` scopes should be considered inert from the perspective of
Fizz since we assume they'll only be used in rare and adverse
circumstances. When we added preload support for img tags we did not
include the noscript scope check in the opt-out for preloading. This
change adds it in

fixes: #27910

DiffTrain build for [dc6a7e01e1](https://github.com/facebook/react/commit/dc6a7e01e1d2fa5eb4974f9bb66e9e8fb40f6ef8)
2024-04-10 19:19:45 +00:00
rickhanlonii a0cbdd5fe2 Hardcode disableIEWorkarounds for www (#28811)
This has landed and is true everywhere, but let's keep the flag until it
lands in the stable release.

DiffTrain build for [84cb3b4cb2](https://github.com/facebook/react/commit/84cb3b4cb250bd592f4eb9495e66b50d33c8cd1e)
2024-04-10 15:19:16 +00:00
acdlite 7ea7a3bd01 Warn if outdated JSX transform is detected (#28781)
We want to warn if we detect that an app is using an outdated JSX
transform. We can't just warn if `createElement` is called because we
still support `createElement` when it's called manually. We only want to
warn if `createElement` is output by the compiler.

The heuristic is to check for a `__self` prop, which is an optional,
internal prop that older transforms used to pass to `createElement` for
better debugging in development mode.

If `__self` is present, we `console.warn` once with advice to upgrade to
the modern JSX transform. Subsequent elements will not warn.

There's a special case we have to account for: when a static "key" prop
is defined _after_ a spread, the modern JSX transform outputs
`createElement` instead of `jsx`. (This is because with `jsx`, a spread
key always takes precedence over a static key, regardless of the order,
whereas `createElement` respects the order.) To avoid a false positive
warning, we skip the warning whenever a `key` prop is present.

DiffTrain build for [ed3c65caf0](https://github.com/facebook/react/commit/ed3c65caf042f75fe2fdc2a5e568a9624c6175fb)
2024-04-09 21:18:26 +00:00
acdlite 442049b3dc Fix: Suspend while recovering from hydration error (#28800)
Fixes a bug that happens when an error occurs during hydration, React
switches to client rendering, and then the client render suspends. It
works correctly if there's a Suspense boundary on the stack, but not if
it happens in the shell of the app.

Prior to this fix, the app would crash with an "Unknown root exit
status" error.

I left a TODO comment for how we might refactor this code to be less
confusing in the future.

DiffTrain build for [3f9e237a2f](https://github.com/facebook/react/commit/3f9e237a2feb74f1fca23b76d9d2e9e1713e2ba1)
2024-04-09 21:16:28 +00:00
josephsavona a85aedcb36 Attempt to fix diff syncing for Meta (#28801)
#28796 broke Meta's PR syncing tool, hoping this fixes it

DiffTrain build for [64c8d2d45d](https://github.com/facebook/react/commit/64c8d2d45d49dbb2f59ea23e5e739eb79e124abc)
2024-04-09 21:10:03 +00:00
gnoff e992aaabe5 [DOM] Infer react-server entries bundles if not explicitly configured (#28795)
When packaging we want to infer that a bundle exists for a
`react-server` file even if it isn't explicitly configured. This is
useful in particular for the react-server entrypoints that error on
import that were recently added to `react-dom`

This change also cleans up a wayward comment left behind in a prior PR

DiffTrain build for [7f93cb41c8](https://github.com/facebook/react/commit/7f93cb41c8e1352eec158e508bc612025425266d)
2024-04-09 17:44:10 +00:00
sebmarkbage 1c05d71996 Rename SECRET INTERNALS to __CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE (#28789)
Follow up to #28783 and #28786.

Since we've changed the implementations of these we can rename them to
something a bit more descriptive while we're at it, since anyone
depending on them will need to upgrade their code anyway.

"react" with no condition:
`__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE`
"react" with "react-server" condition:
`__SERVER_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE`
"react-dom":
`__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE`

DiffTrain build for [f613165357](https://github.com/facebook/react/commit/f6131653570bbbf62d642ba9343b9cd0ab1ae97c)
2024-04-09 16:26:09 +00:00
rickhanlonii 3c7d51c10c Soften useFormState warning (#28788)
It's not deprecated, it's really just renamed. Let's make the warning
less scary.

DiffTrain build for [9644d206e8](https://github.com/facebook/react/commit/9644d206e8d92d0e31a9252d78933a48c62eb427)
2024-04-09 03:26:44 +00:00
sebmarkbage dad460473c Rename The Secret Export of Server Internals (#28786)
We have a different set of dispatchers that Flight uses. This also
includes the `jsx-runtime` which must also be aliased to use the right
version.

To ensure the right versions are used together we rename the export of
the SharedInternals from 'react' and alias it in relevant bundles.

DiffTrain build for [c771016e19](https://github.com/facebook/react/commit/c771016e19384e4b6e42e1c275bdf03fe51c2907)
2024-04-09 02:39:45 +00:00
sebmarkbage 74e25ca142 Flatten ReactSharedInternals (#28783)
This is similar to #28771 but for isomorphic. We need a make over for
these dispatchers anyway so this is the first step. Also helps flush out
some internals usage that will break anyway.

It flattens the inner mutable objects onto the ReactSharedInternals.

DiffTrain build for [d50323eb84](https://github.com/facebook/react/commit/d50323eb845c5fde0d720cae888bf35dedd05506)
2024-04-08 23:27:08 +00:00
gnoff 550d416dcb [Float] treat props.async in Float consistent with the rest of react-dom (#26760)
Treat async (boolean prop) consistently with Float. Previously float
checked if `props.async === true` (or not true) but the rest of
react-dom considers anything truthy that isn't a function or symbol as
`true`. This PR normalizes the Float behavior.

DiffTrain build for [f62cf8c620](https://github.com/facebook/react/commit/f62cf8c62052ae780d351090013f7155cf9a868c)
2024-04-08 21:31:18 +00:00
eps1lon 46384677d3 Add support for transition{run,start,cancel} events (#27345)
DiffTrain build for [dfd3d5af83](https://github.com/facebook/react/commit/dfd3d5af83cadd9bfc904c0a62a30adc20e414c9)
2024-04-08 21:27:09 +00:00
gnoff 3c33835c1b [Fiber] Use real event priority for hydration scheduling (#28765)
Stacked on #28751

Historically explicit hydration scheduling used the reconciler's update
priority to schedule the hydration. There was a lingering todo to switch
to using event priority in the absence of an explicit update priority.
This change updates the hydration priority by referring to the event
priority if no update priority is set

DiffTrain build for [1f8327f834](https://github.com/facebook/react/commit/1f8327f834d923aa5a99cc0e81d2c9fc9d38c75d)
2024-04-08 21:10:00 +00:00
gnoff 7739cd4a3d [DOM] Shrink ReactDOMCurrentDispatcher method names (#28770)
Stacked on #28771

ReactDOMCurrentDispatcher has longer property names for various methods.
These methods are only ever called internally and don't need to be
represented with as many characters. This change shortens the names and
aligns them with the hint codes we use in Flight. This alignment is
passive since not all dispatcher methods will exist as flight
instructions but where they can line up it seems reasonable to make them
do so

DiffTrain build for [97c90ed883](https://github.com/facebook/react/commit/97c90ed8835401e325e42de22f38a803c5e6fc6d)
2024-04-08 20:59:15 +00:00
gnoff 9ea88c8279 [DOM] Shrink ReactDOMSharedInternals source representation (#28771)
Stacked on #28751

ReactDOMSharedInternals uses properties of considerable length to model
mutuable state. These properties are not mangled during minification and
contribute a not insigificant amount to the uncompressed bundle size and
to a lesser degree compressed bundle size.

This change rewrites the DOMInternals in a way that shortens property
names so we can have smaller builds.
It also treats the entire object as a mutable container rather than
having different mutable sub objects.

The same treatment should be given to ReactSharedInternals

DiffTrain build for [9007fdc8f1](https://github.com/facebook/react/commit/9007fdc8f103a5d9247be384791496db9a3be91d)
2024-04-08 20:44:42 +00:00
sebmarkbage d1d30ea7f1 [Flight] Allow lazily resolving outlined models (#28780)
We used to assume that outlined models are emitted before the reference
(which was true before Blobs). However, it still wasn't safe to assume
that all the data will be available because an "import" (client
reference) can be async and therefore if it's directly a child of an
outlined model, it won't be able to update in place.

This is a similar problem as the one hit by @unstubbable in #28669 with
elements, but a little different since these don't follow the same way
of wrapping.

I don't love the structuring of this code which now needs to pass a
first class mapper instead of just being known code. It also shares the
host path which is just an identity function. It wouldn't necessarily
pass my own review but I don't have a better one for now. I'd really
prefer if this was done at a "row" level but that ends up creating even
more code.

Add test for Blob in FormData and async modules in Maps.

DiffTrain build for [14f50ad155](https://github.com/facebook/react/commit/14f50ad1554f0adf20fa1b5bc62859ed32be0bc6)
2024-04-08 19:44:09 +00:00
gnoff b1a0af935a [DOM] move flushSync out of the reconciler (#28500)
This PR moves `flushSync` out of the reconciler. there is still an
internal implementation that is used when these semantics are needed for
React methods such as `unmount` on roots.

This new isomorphic `flushSync` is only used in builds that no longer
support legacy mode.

Additionally all the internal uses of flushSync in the reconciler have
been replaced with more direct methods. There is a new
`updateContainerSync` method which updates a container but forces it to
the Sync lane and flushes passive effects if necessary. This combined
with flushSyncWork can be used to replace flushSync for all instances of
internal usage.

We still maintain the original flushSync implementation as
`flushSyncFromReconciler` because it will be used as the flushSync
implementation for FB builds. This is because it has special legacy mode
handling that the new isomorphic implementation does not need to
consider. It will be removed from production OSS builds by closure
though

DiffTrain build for [4c12339ce3](https://github.com/facebook/react/commit/4c12339ce3fa398050d1026c616ea43d43dcaf4a)
2024-04-08 16:07:33 +00:00
gnoff ffde2c00a9 [Fiber] Move updatePriority tracking to renderers (#28751)
Currently updatePriority is tracked in the reconciler. `flushSync` is
going to be implemented reconciler agnostic soon and we need to move the
tracking of this state to the renderer and out of reconciler. This
change implements new renderer bin dings for getCurrentUpdatePriority
and setCurrentUpdatePriority.

I was originally going to have the getter also do the event priority
defaulting using window.event so we eliminate getCur rentEventPriority
but this makes all the callsites where we store the true current
updatePriority on the stack harder to work with so for now they remain
separate.

I also moved runWithPriority to the renderer since it really belongs
whereever the state is being managed and it is only currently exposed in
the DOM renderer.

Additionally the current update priority is not stored on
ReactDOMSharedInternals. While not particularly meaningful in this
change it opens the door to implementing `flushSync` outside of the
reconciler

DiffTrain build for [8e1462e8c4](https://github.com/facebook/react/commit/8e1462e8c471fbec98aac2b3e1326498d0ff7139)
2024-04-08 15:58:13 +00:00
acdlite aabb356a7e jsx: Remove unnecessary hasOwnProperty check (#28775)
Follow up to #28768.

The modern JSX runtime (`jsx`) does not need to check if each prop is a
direct property with `hasOwnProperty` because the compiler always passes
a plain object.

I'll leave the check in the old JSX runtime (`createElement`) since that
one can be called manually with any kind of object, and if there were
old user code that relied on this for some reason, it would be using
that runtime.

DiffTrain build for [0b3b8a6a35](https://github.com/facebook/react/commit/0b3b8a6a354b90fe76a9d82bb34487e5d2f71203)
2024-04-08 15:18:01 +00:00
sebmarkbage c093e5beb3 [Flight] Support FormData from Server to Client (#28754)
We currently support FormData for Replies mainly for Form Actions. This
supports it in the other direction too which lets you return it from an
action as the response. Mainly for parity.

We don't really recommend that you just pass the original form data back
because the action is supposed to be able to clear fields and such but
you could potentially at least use this as the format and could clear
some fields.

We could potentially optimize this with a temporary reference if the
same object was passed to a reply in case you use it as a round trip to
avoid serializing it back again. That way the action has the ability to
override it to clear fields but if it doesn't you get back the same as
you sent.

#28755 adds support for Blobs when the `enableBinaryFlight` is enabled
which allows them to be used inside FormData too.

DiffTrain build for [2acfb7b609](https://github.com/facebook/react/commit/2acfb7b60922bdc8376dd144ca7bc532df78254b)
2024-04-05 18:37:15 +00:00
acdlite 2cfe8d32dd Fast JSX: Don't clone props object (#28768)
(Unless "key" is spread onto the element.)

Historically, the JSX runtime clones the props object that is passed in.
We've done this for two reasons.

One reason is that there are certain prop names that are reserved by
React, like `key` and (before React 19) `ref`. These are not actual
props and are not observable by the target component; React uses them
internally but removes them from the props object before passing them to
userspace.

The second reason is that the classic JSX runtime, `createElement`, is
both a compiler target _and_ a public API that can be called manually.
Therefore, we can't assume that the props object that is passed into
`createElement` won't be mutated by userspace code after it is passed
in.

However, the new JSX runtime, `jsx`, is not a public API — it's solely a
compiler target, and the compiler _will_ always pass a fresh, inline
object. So the only reason to clone the props is if a reserved prop name
is used.

In React 19, `ref` is no longer a reserved prop name, and `key` will
only appear in the props object if it is spread onto the element.
(Because if `key` is statically defined, the compiler will pass it as a
separate argument to the `jsx` function.) So the only remaining reason
to clone the props object is if `key` is spread onto the element, which
is a rare case, and also triggers a warning in development.

In a future release, we will not remove a spread key from the props
object. (But we'll still warn.) We'll always pass the object straight
through.

The expected impact is much faster JSX element creation, which in many
apps is a significant slice of the overall runtime cost of rendering.

DiffTrain build for [d1547defe3](https://github.com/facebook/react/commit/d1547defe34cee6326a61059148afc83228d8ecf)
2024-04-05 17:30:21 +00:00
acdlite c7d55de717 Make class prop resolution faster (#28766)
`delete` causes an object (in V8, and maybe other engines) to deopt to a
dictionary instead of a class. Instead of `assign` + `delete`, manually
iterate over all the properties, like the JSX runtime does.

To avoid copying the object twice I moved the `ref` prop removal to come
before handling default props. If we already cloned the props to remove
`ref`, then we can skip cloning again to handle default props.

DiffTrain build for [bfd8da807c](https://github.com/facebook/react/commit/bfd8da807c75a2d123627415f9eaf2d36ac3ed6a)
2024-04-05 17:11:28 +00:00
sebmarkbage 1d8cde0408 [Flight] Support Blobs from Server to Client (#28755)
We currently support Blobs when passing from Client to Server so this
adds it in the other direction for parity - when `enableFlightBinary` is
enabled.

We intentionally only support the `Blob` type to pass-through, not
subtype `File`. That's because passing additional meta data like
filename might be an accidental leak. You can still pass a `File`
through but it'll appear as a `Blob` on the other side. It's also not
possible to create a faithful File subclass in all environments without
it actually being backed by a file.

This implementation isn't great but at least it works. It creates a few
indirections. This is because we need to be able to asynchronously emit
the buffers but we have to "block" the parent object from resolving
while it's loading.

Ideally, we should be able to create the Blob on the client early and
then stream in it lazily. Because the Blob API doesn't guarantee that
the data is available synchronously. Unfortunately, the native APIs
doesn't have this. We could implement custom versions of all the data
read APIs but then the blobs still wouldn't work with native APIs. So we
just have to wait until Blob accepts a stream in the constructor.

We should be able to stream each chunk early in the protocol though even
though we can't unblock the parent until they've all loaded. I didn't do
this yet mostly because of code structure and I'm lazy.

DiffTrain build for [cbb6f2b546](https://github.com/facebook/react/commit/cbb6f2b5461cdce282c7e47b9c68a0897d393383)
2024-04-05 16:54:31 +00:00
sebmarkbage 75004cde87 Track Owner for Server Components in DEV (#28753)
This implements the concept of a DEV-only "owner" for Server Components.
The owner concept isn't really super useful. We barely use it anymore,
but we do have it as a concept in DevTools in a couple of cases so this
adds it for parity. However, this is mainly interesting because it could
be used to wire up future owner-based stacks.

I do this by outlining the DebugInfo for a Server Component
(ReactComponentInfo). Then I just rely on Flight deduping to refer to
that. I refer to the same thing by referential equality so that we can
associate a Server Component parent in DebugInfo with an owner.

If you suspend and replay a Server Component, we have to restore the
same owner. To do that, I did a little ugly hack and stashed it on the
thenable state object. Felt unnecessarily complicated to add a stateful
wrapper for this one dev-only case.

The owner could really be anything since it could be coming from a
different implementation. Because this is the first time we have an
owner other than Fiber, I have to fix up a bunch of places that assumes
Fiber. I mainly did the `typeof owner.tag === 'number'` to assume it's a
Fiber for now.

This also doesn't actually add it to DevTools / RN Inspector yet. I just
ignore them there for now.

Because Server Components can be async the owner isn't tracked after an
await. We need per-component AsyncLocalStorage for that. This can be
done in a follow up.

DiffTrain build for [f33a6b69c6](https://github.com/facebook/react/commit/f33a6b69c6cb406ea0cc51d07bc4d3fd2d8d8744)
2024-04-05 16:53:53 +00:00
acdlite e6ea24b07b Move string ref coercion to JSX runtime (#28473)
Based on:

- #28464

---

This moves the entire string ref implementation out Fiber and into the
JSX runtime. The string is converted to a callback ref during element
creation. This is a subtle change in behavior, because it will have
already been converted to a callback ref if you access element.prop.ref
or element.ref. But this is only for Meta, because string refs are
disabled entirely in open source. And if it leads to an issue in
practice, the solution is to switch to a different ref type, which Meta
is going to do regardless.

DiffTrain build for [e3ebcd54b9](https://github.com/facebook/react/commit/e3ebcd54b98a4f8f5a9f7e63982fa75578b648ed)
2024-04-05 14:58:03 +00:00
acdlite 769be695f5 Remove defaultProps support (except for classes) (#28733)
This removes defaultProps support for all component types except for
classes. We've chosen to continue supporting defaultProps for classes
because lots of older code relies on it, and unlike function components,
(which can use default params), there's no straightforward alternative.

By implication, it also removes support for setting defaultProps on
`React.lazy` wrapper. So this will not work:

```js
const MyClassComponent = React.lazy(() => import('./MyClassComponent'));
// MyClassComponent is not actually a class; it's a lazy wrapper. So
// defaultProps does not work.
MyClassComponent.defaultProps = { foo: 'bar' };
```

However, if you set the default props on the class itself, then it's
fine.

For classes, this change also moves where defaultProps are resolved.
Previously, defaultProps were resolved by the JSX runtime. This change
is only observable if you introspect a JSX element, which is relatively
rare but does happen.

In other words, previously `<ClassWithDefaultProp />.props.aDefaultProp`
would resolve to the default prop value, but now it does not.

DiffTrain build for [48b4ecc901](https://github.com/facebook/react/commit/48b4ecc9012638ed51b275aad24b2086b8215e32)
2024-04-04 15:04:09 +00:00
sebmarkbage e0fc90e076 Use a Wrapper Error for onRecoverableError with a "cause" Field for the real Error (#28736)
We basically have four kinds of recoverable errors:

- Hydration mismatches.
- Server errored but client didn't.
- Hydration render errored but client render didn't (in Root or Suspense
boundary).
- Concurrent render errored but synchronous render didn't.

For the first three we log an additional error that the root or Suspense
boundary didn't error. This provides some context about what happened.
However, the problem is that for hydration mismatches that's unnecessary
extra context that is confusing. We also don't log any additional
context for concurrent render errors that could recover. This used to be
the only recoverable error so it didn't need extra context but now we
need to distinguish them. When we log these to `reportError` it's
confusing to just see the error because you didn't see anything error on
the page. It's also hard to group them together as one.

In this PR, I remove the unnecessary context for hydration mismatches.

For hydration and concurrent errors, I now wrap them in an error that
describes that what happened but then use the new `cause` field to link
the original error so we can keep that as the cause. The error that
happened was that hydration client rendered or you deopted to sync
render, the cause of that error is some other error.

For server errors, we control the Error object so I already had added
some context to that error object's message. Since we hide the message
in prod, it's nice not to have the raw message in DEV neither. We could
potentially split these into two errors for parity though.

DiffTrain build for [6090cab099](https://github.com/facebook/react/commit/6090cab099a8f7f373e04c7eb2937425a8f80f80)
2024-04-04 01:58:18 +00:00
sebmarkbage 2d934393d1 Emit Server Error Prefix in the .stack Property Too (#28738)
Follow up to #28684.

V8 includes the message in the stack and printed errors include just the
stack property which is assumed to contain the message. Without this,
the prefix doesn't get printed in the console.

<img width="578" alt="Screenshot 2024-04-03 at 6 32 04 PM"
src="https://github.com/facebook/react/assets/63648/d98a2db4-6ebc-4805-b669-59f449dfd21f">

A possible alternative would be to use a nested error with a `cause`
like #28736 but that would need some more involved serializing since
this prefix is coming from the server. Perhaps as a separate attribute.

DiffTrain build for [583eb6770d](https://github.com/facebook/react/commit/583eb6770d56e9793d3660bd9c6782fdebc93729)
2024-04-04 01:57:39 +00:00
kassens ce3ba22cf3 Cleanup enableUseRefAccessWarning flag (#28699)
Cleanup enableUseRefAccessWarning flag

I don't think this flag has a path forward in the current
implementation. The detection by stack trace is too brittle to detect
the lazy initialization pattern reliably (see e.g. some internal tests
that expect the warning because they use lazy intialization, but a
slightly different pattern then the expected pattern.

I think a new version of this could be to fully ban ref access during
render with an alternative API for the exceptional cases that today
require ref access during render.

DiffTrain build for [20e710aeab](https://github.com/facebook/react/commit/20e710aeab3e03809c82d134171986ea270026a0)
2024-04-03 17:40:38 +00:00
acdlite a491103917 Classes consume ref prop during SSR, too (#28731)
Same as #28719 but for SSR.

DiffTrain build for [3761acb42b](https://github.com/facebook/react/commit/3761acb42bf9979314fff130d4d9505408bcb651)
2024-04-03 17:00:46 +00:00
kassens 6cdcf5b723 Cleanup enableBigIntSupport flag (#28711)
Cleanup enableBigIntSupport flag

DiffTrain build for [7a2609eedc](https://github.com/facebook/react/commit/7a2609eedc571049a3272e60d5f7d84601ffca3f)
2024-04-03 13:30:33 +00:00