Along with all the places using it like the `_debugSource` on Fiber.
This still lets them be passed into `createElement` (and JSX dev
runtime) since those can still be used in existing already compiled code
and we don't want that to start spreading to DOM attributes.
We used to have a DEV mode that compiles the source location of JSX into
the compiled output. This was nice because we could get the actual call
site of the JSX (instead of just somewhere in the component). It had a
bunch of issues though:
- It only works with JSX.
- The way this source location is compiled is different in all the
pipelines along the way. It relies on this transform being first and the
source location we want to extract but it doesn't get preserved along
source maps and don't have a way to be connected to the source hosted by
the source maps. Ideally it should just use the mechanism other source
maps use.
- Since it's expensive it only works in DEV so if it's used for
component stacks it would vary between dev and prod.
- It only captures the callsite of the JSX and not the stack between the
component and that callsite. In the happy case it's in the component but
not always.
Instead, we have another zero-cost trick to extract the call site of
each component lazily only if it's needed. This ensures that component
stacks are the same in DEV and PROD. At the cost of worse line number
information.
The better way to get the JSX call site would be to get it from `new
Error()` or `console.createTask()` inside the JSX runtime which can
capture the whole stack in a consistent way with other source mappings.
We might explore that in the future.
This removes source location info from React DevTools and React Native
Inspector. The "jump to source code" feature or inspection can be made
lazy instead by invoking the lazy component stack frame generation. That
way it can be made to work in prod too. The filtering based on file path
is a bit trickier.
When redesigned this UI should ideally also account for more than one
stack frame.
With this change the DEV only Babel transforms are effectively
deprecated since they're not necessary for anything.
DiffTrain build for [37d901e2b8](https://github.com/facebook/react/commit/37d901e2b81e12d40df7012c6f8681b8272d2555)
There's no need to separate strict mode from strict effects mode any
more.
I didn't clean up the `StrictEffectMode` fiber flag, because it's used
to prevent strict effects in legacy mode. I could replace those checks
with `LegacyMode` checks, but when we remove legacy mode, we can remove
that flag and condense them into one StrictMode flag away.
DiffTrain build for [3d1da1f9ab](https://github.com/facebook/react/commit/3d1da1f9ab7d54984c096e6a04c8729f3a50fd8a)
Treat `<a href="" />` the same with and without
`enableFilterEmptyStringAttributesDOM`
in https://github.com/facebook/react/pull/18513 we started to warn and
ignore for empty `href` and `src` props since it usually hinted at a
mistake. However, for anchor tags there's a valid use case since `<a
href=""></a>` will by spec render a link to the current page. It could
be used to reload the page without having to rely on browser
affordances.
The implementation for Fizz is in the spirit of
https://github.com/facebook/react/pull/21153. I gated the fork behind
the flag so that the fork is DCE'd when the flag is off.
DiffTrain build for [f3ce87ab65](https://github.com/facebook/react/commit/f3ce87ab650f07774e1df9bc3f8033e023973d10)
Previously we only warned during a synchronous update, because we
eventually want to support async client components in controlled
scenarios, like during navigations. However, we're going to warn in all
cases for now until we figure out how that should work.
DiffTrain build for [178f435194](https://github.com/facebook/react/commit/178f4351947a842ff0b56700e9115b25ae8f20d0)
To make React.startTransition more consistent with the hook form of
startTransition, we capture errors thrown by the scope function and pass
them to the global reportError function. (This is also what we do as a
default for onRecoverableError.)
This is a breaking change because it means that errors inside of
startTransition will no longer bubble up to the caller. You can still
catch the error by putting a try/catch block inside of the scope
function itself.
We do the same for async actions to prevent "unhandled promise
rejection" warnings.
The motivation is to avoid a refactor hazard when changing from a sync
to an async action, or from useTransition to startTransition.
DiffTrain build for [60f190a559](https://github.com/facebook/react/commit/60f190a55948a7512d4e2a336f03b45fd38d6a80)
## Summary
In the precendences Map every key is prefixed with `p`. This fixes one
case where this is missing.
## How did you test this change?
<!--
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.
-->
DiffTrain build for [763612647c](https://github.com/facebook/react/commit/763612647ceb66d95f728af896ca5e18a8181db8)
This adds support for async actions to the "isomorphic" version of
startTransition (i.e. the one exported by the "react" package).
Previously, async actions were only supported by the startTransition
that is returned from the useTransition hook.
The interesting part about the isomorphic startTransition is that it's
not associated with any particular root. It must work with updates to
arbitrary roots, or even arbitrary React renderers in the same app. (For
example, both React DOM and React Three Fiber.)
The idea is that React.startTransition should behave as if every root
had an implicit useTransition hook, and you composed together all the
startTransitions provided by those hooks. Multiple updates to the same
root will be batched together. However, updates to one root will not be
batched with updates to other roots.
Features like useOptimistic work the same as with the hook version.
There is one difference from from the hook version of startTransition:
an error triggered inside an async action cannot be captured by an error
boundary, because it's not associated with any particular part of the
tree. You should handle errors the same way you would in a regular
event, e.g. with a global error event handler, or with a local
`try/catch`.
DiffTrain build for [85b296e9b6](https://github.com/facebook/react/commit/85b296e9b6ded4accd9ec3389297f95091fb1ac0)
If there are multiple updates inside an async action, they should all be
rendered in the same batch, even if they are separate by an async
operation (`await`). We currently implement this by suspending in the
`useTransition` hook to block the update from committing until all
possible updates have been scheduled by the action. The reason we did it
this way is so you can "cancel" an action by navigating away from the UI
that triggered it.
The problem with that approach, though, is that even if you navigate
away from the `useTransition` hook, the action may have updated shared
parts of the UI that are still in the tree. So we may need to continue
suspending even after the `useTransition` hook is deleted.
In other words, the lifetime of an async action scope is longer than the
lifetime of a particular `useTransition` hook.
The solution is to suspend whenever _any_ update that is part of the
async action scope is unwrapped during render. So, inside useState and
useReducer.
This fixes a related issue where an optimistic update is reverted before
the async action has finished, because we were relying on the
`useTransition` hook to prevent the optimistic update from finishing.
This also prepares us to support async actions being passed to the
non-hook form of `startTransition` (though this isn't implemented yet).
DiffTrain build for [11c9fd0c53](https://github.com/facebook/react/commit/11c9fd0c53133f24f5270d36591b65b8fc2ebd25)
This fixes a bug that happened when the canonical value passed to
useOptimistic without an accompanying call to setOptimistic. In this
scenario, useOptimistic should pass through the new canonical value.
I had written tests for the more complicated scenario, where a new value
is passed while there are still pending optimistic updates, but not this
simpler one.
DiffTrain build for [60a927d04a](https://github.com/facebook/react/commit/60a927d04ad3888facebcdf7da620aa1cfc9528f)
If this is a client reference we shouldn't dot into it, which would
throw in the proxy.
Interestingly our client references don't really have a `name`
associated with them for debug information so a component type doesn't
show up in error logs even though it seems like it should.
DiffTrain build for [0ac3ea471f](https://github.com/facebook/react/commit/0ac3ea471fbcb7d79bc7d36179e960c72c779e76)
Fixes a bug in the experimental `initialValue` option for
`useDeferredValue` (added in #27500).
If rendering the `initialValue` causes the tree to suspend, React should
skip it and switch to rendering the final value instead. It should not
wait for `initialValue` to resolve.
This is not just an optimization, because in some cases the initial
value may _never_ resolve — intentionally. For example, if the
application does not provide an instant fallback state. This capability
is, in fact, the primary motivation for the `initialValue` API.
I mostly implemented this correctly in the original PR, but I missed
some cases where it wasn't working:
- If there's no Suspense boundary between the `useDeferredValue` hook
and the component that suspends, and we're not in the shell of the
transition (i.e. there's a parent Suspense boundary wrapping the
`useDeferredValue` hook), the deferred task would get incorrectly
dropped.
- Similarly, if there's no Suspense boundary between the
`useDeferredValue` hook and the component that suspends, and we're
rendering a synchronous update, the deferred task would get incorrectly
dropped.
What these cases have in common is that it causes the `useDeferredValue`
hook itself to be replaced by a Suspense fallback. The fix was the same
for both. (It already worked in cases where there's no Suspense fallback
at all, because those are handled differently, at the root.)
The way I discovered this was when investigating a particular bug in
Next.js that would happen during a 'popstate' transition (back/forward),
but not during a regular navigation. That's because we render popstate
transitions synchronously to preserve browser's scroll position — which
in this case triggered the second scenario above.
DiffTrain build for [f1039be4a4](https://github.com/facebook/react/commit/f1039be4a48384e7e4b0a87d4d92c48e900053b9)
This PR adds a new FB-specific configuration of Flight. We also need to
bundle a version of ReactSharedSubset that will be used for running
Flight on the server.
This initial implementation does not support server actions yet.
The FB-Flight still uses the text protocol on the server (the flag
`enableBinaryFlight` is set to false). It looks like we need some
changes in Hermes to properly support this binary format.
DiffTrain build for [c17a27ef49](https://github.com/facebook/react/commit/c17a27ef492d9812351aecdfb017488e8e8404ce)
In order to make Haste work with React's artifacts, It is important to
keep headers in this format:
```
/**
* ...
...
* ...
*/
```
For optimization purposes, Closure compiler will actually modify these
headers by removing * prefixes, which is expected.
We should pass sources to the compiler without license headers, with
these changes the current flow will be:
1. Apply top-level definitions. For UMD-bundles, for example, or
DEV-only bundles (e. g. `if (__DEV__) { ...`)
2. Apply licence headers for artifacts with sourcemaps: oss-production
and oss-profiling bundles, they don't need to preserve the header format
to comply with Haste. We need to apply these headers before passing
sources to Closure, so it can build correct mappings for sourcemaps.
3. Pass these sources to closure compiler for minification and
sourcemaps building.
4. Apply licence headers for artifacts without sourcemaps: dev bundles,
fb bundles. This way the header style will be preserved and not changed
by Closure.
DiffTrain build for [c47c306a7a](https://github.com/facebook/react/commit/c47c306a7a23d3c796b148d303764e2832da480c)
## Summary
There's a bug with the existing stack comparison algorithm in
`describeNativeComponentFrame` — specifically how it attempts to find a
common root frame between the control and sample stacks. This PR
attempts to fix that bug by injecting a frame that can have a guaranteed
string in it for us to search for in both stacks to find a common root.
## Brief Background/How it works now
Right now `describeNativeComponentFrame` does the following to leverage
native browser/VM stack frames to get details (e.g. script path, row and
col #s) for a single component:
1. Throwing and catching a control error in the function
2. Calling the component which should eventually throw an error (most of
the time), that we'll catch as our sample error.
3. Diffing the stacks in the control and sample errors to find the line
which should represent our component call.
## What's broken
To account for potential stack trace truncation, the stack diffing
algorithm first attempts to find a common "root" frame by inspecting the
earliest frame of the sample stack and searching for an identical frame
in the control stack starting from the bottom. However, there are a
couple of scenarios which I've hit that cause the above approach to not
work correctly.
First, it's possible that for render passes of extremely large component
trees to have a lot of repeating internal react function calls, which
can result in an incorrect common or "root" frame found. Here's a small
example from a stack trace using React Fizz for SSR.
Our control frame can look like this:
```
Error:
at Fake (...)
at construct (native)
at describeNativeComponentFrame (...)
at describeClassComponentFrame (...)
at getStackByComponentStackNode (...)
at getCurrentStackInDEV (...)
at renderNodeDestructive (...)
at renderElement (...)
at renderNodeDestructiveImpl (...) // <-- Actual common root frame with the sample stack
at renderNodeDestructive (...)
at renderElement (...)
at renderNodeDestructiveImpl (...) // <-- Incorrectly chosen common root frame
at renderNodeDestructive (...)
```
And our sample stack can look like this:
```
Error:
at set (...)
at PureComponent (...)
at call (native)
at apply (native)
at ErrorBoundary (...)
at construct (native)
at describeNativeComponentFrame (...)
at describeClassComponentFrame (...)
at getStackByComponentStackNode (...)
at getCurrentStackInDEV (...)
at renderNodeDestructive (...)
at renderElement (...)
at renderNodeDestructiveImpl (...) // <-- Root frame that's common in the control stack
```
Here you can see that the earliest trace in the sample stack, the
`renderNodeDestructiveImpl` call, can exactly match with multiple
`renderNodeDestructiveImpl` calls in the control stack (including file
path and line + col #s). Currently the algorithm will chose the
earliest/last frame with the `renderNodeDestructiveImpl` call (which is
the second last frame in our control stack), which is incorrect. The
actual matching frame in the control stack is the latest or first frame
(when traversing from the top) with the `renderNodeDestructiveImpl`
call. This leads to the rest of the stack diffing associating an
incorrect frame (`at getStackByComponentStackNode (...)`) for the
component.
Another issue with this approach is that it assumes all VMs will
truncate stack traces at the *bottom*, [which isn't the case for the
Hermes
VM](https://github.com/facebook/hermes/blob/df07cf713a84a4434c83c08cede38ba438dc6aca/lib/VM/JSError.cpp#L688-L699)
which **truncates stack traces in the middle**, placing a
```
at renderNodeDestructiveImpl (...)
... skipping {n} frames
at renderNodeDestructive (...)
```
line in the middle of the stack trace for all stacks that contain more
than 100 traces. This causes stack traces for React Native apps using
the Hermes VM to potentially break for large component trees. Although
for this specific case with Hermes, it's possible to account for this by
either manually grepping and removing the `... skipping` line and
everything below it (see draft PR: #26999), or by implementing the
non-standard `prepareStackTrace` API which Hermes also supports to
manually generate a stack trace that truncates from the bottom ([example
implementation](https://github.com/facebook/react/compare/main...KarimP:react:component-stack-hermes-fix)).
## The Fix
I found different ways to go about fixing this. The first was to search
for a common stack frame starting from the top/latest frame. It's a
relatively small change ([see
implementation](https://github.com/facebook/react/compare/main...KarimP:react:component-stack-fix-2)),
although it is less performant by being n^2 (albeit with `n`
realistically being <= 5 here). It's also a bit more buggy for class
components given that different VMs insert a different amount of
additional lines for new/construct calls...
Another fix would be to actually implement a [longest common
substring](https://en.wikipedia.org/wiki/Longest_common_substring)
algorithm, which can also be roughly n^2 time (assuming the longest
common substring between control and sample will be most of the sample
frame).
The fix I ended up going with was have the lines that throw the control
error and the lines that call/instantiate the component be inside a
distinct method under an object property
(`"DescribeNativeComponentFrameRoot"`). All major VMs (Safari's
JavaScriptCore, Firefox's SpiderMonkey, V8, Hermes, and Bun) should
display the object property name their stack trace. I've also set the
`name` and `displayName` properties for method as well to account for
minification, any advanced optimizations (e.g. key crushing), and VM
inconsistencies (both Bun and Safari seem to exclusively use the value
under `displayName` and not `name` in traces for methods defined under
an object's own property...).
We can then find this "common" frame by simply finding the line that has
our special method name (`"DescribeNativeComponentFrameRoot"`), and the
rest of the code to determine the actual component line works as
expected. If by any chance we don't find a frame with our special method
name in either control or sample stack traces, we then revert back to
the existing approach mentioned above by searching for the last line of
the sample frame in the control frame.
## How did you test this change?
1. There are bunch of existing tests that ensure a properly formatted
component trace is logged for certain scenarios, so I ensured the
existing full test suite passed
2. I threw an error in a component that's deep in the component
hierarchy of a large React app (facebook) to ensure there's stack trace
truncation, and ensured the correct component stack trace was logged for
Chrome, Safari, and Firefox, and with and without minification.
3. Ran a large React app (facebook) on the Hermes VM, threw an error in
a component that's deep in the component hierarchy, and ensured that
component frames are generated despite stack traces being truncated in
the middle.
DiffTrain build for [88b00dec47](https://github.com/facebook/react/commit/88b00dec4778ffa230cceca81af3328f49e1efd9)
<!--
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
This PR updates the Rollup build pipeline to generate sourcemaps for
production build artifacts like `react-dom.production.min.js`.
It requires the Rollup v3 changes that were just merged in #26442 .
Sourcemaps are currently _only_ generated for build artifacts that are
_truly_ "production" - no sourcemaps will be generated for development,
profiling, UMD, or `shouldStayReadable` artifacts.
The generated sourcemaps contain the bundled source contents right
before that chunk was minified by Closure, and _not_ the original source
files like `react-reconciler/src/*`. This better reflects the actual
code that is running as part of the bundle, with all the feature flags
and transformations that were applied to the source files to generate
that bundle. The sourcemaps _do_ still show comments and original
function names, thus improving debuggability for production usage.
Fixes#20186 .
<!--
Explain the **motivation** for making this change. What existing problem
does the pull request solve?
-->
This allows React users to actually debug a readable version of the
React bundle in production scenarios. It also allows other tools like
[Replay](https://replay.io) to do a better job inspecting the React
source when stepping through.
## How did you test this change?
- Generated numerous sourcemaps with various combinations of the React
bundle selections
- Viewed those sourcemaps in
https://evanw.github.io/source-map-visualization/ and confirmed via the
visualization that the generated mappings appear to be correct
I've attached a set of production files + their sourcemaps here:
[react-sourcemap-examples.zip](https://github.com/facebook/react/files/11023466/react-sourcemap-examples.zip)
You can drag JS+sourcemap file pairs into
https://evanw.github.io/source-map-visualization/ for viewing.
Examples:
- `react.production.min.js`:

- `react-dom.production.min.js`:

- `use-sync-external-store/with-selector.production.min.js`:

<!--
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.
-->
DiffTrain build for [2c8a139a59](https://github.com/facebook/react/commit/2c8a139a593e0294c3a6953d74b451bd05fdcfca)
Updates useFormState to allow a sync function to be passed as an action.
A form action is almost always async, because it needs to talk to the
server. But since we support client-side actions, too, there's no reason
we can't allow sync actions, too.
I originally chose not to allow them to keep the implementation simpler
but it's not really that much more complicated because we already
support this for actions passed to startTransition. So now it's
consistent: anywhere an action is accepted, a sync client function is a
valid input.
DiffTrain build for [77c4ac2ce8](https://github.com/facebook/react/commit/77c4ac2ce88736bbdfe0b29008b5df931c2beb1e)
The loading state tracking for suspensey CSS is too complicated. Prior
to this change it had a state it could enter into where a stylesheet was
already in the DOM but the loading state did not know it was inserted
causing a later transition to try to insert it again.
This fix is to add proper tracking of insertions on the codepaths that
were missing it. It also modifies the logic of when to suspend based on
whether the stylesheet has already been inserted or not.
This is not 100% correct semantics however because a prior commit could
have inserted a stylesheet and a later transition should ideally be able
to wait on that load before committing. I haven't attempted to fix this
yet however because the loading state tracking is too complicated as it
is and requires a more thorough refactor. Additionally it's not
particularly valuable to delay a transition on a loading stylesheet when
a previous commit also relied on that stylesheet but didn't wait for it
b/c it was sync. I will follow up with an improvement PR later
fixes: https://github.com/facebook/react/issues/27585
DiffTrain build for [a9985529f1](https://github.com/facebook/react/commit/a9985529f1aa55477f0feafe2398d36707cf6108)
By default, partial hydration is given the lowest possible priority,
because until a tree is updated, the server-rendered HTML is assumed to
match the final resolved HTML.
However, this isn't completely true because a component may choose to
"upgrade" itself upon hydration. The simplest example is a component
that calls setState in a useEffect to switch to a richer implementation
of the UI. Another example is a component that doesn't have a server-
rendered implementation, so it intentionally suspends to force a client-
only render.
useDeferredValue is an example, too: the server only renders the first
pass (the initialValue) argument, and relies on the client to upgrade to
the final value.
What we should really do in these cases is emit some information into
the Fizz stream so that Fiber knows to prioritize the hydration of
certain trees. We plan to add a mechanism for this in the future.
In the meantime, though, we can at least ensure that the priority of the
upgrade task is correct once it's "discovered" during hydration. In this
case, the priority of the task spawned by useDeferredValue should have
Transition priority, not Offscreen priority.
DiffTrain build for [779d59374e](https://github.com/facebook/react/commit/779d59374e8e852ce00728d895156a7574e1b456)
During a popstate event, we attempt to render updates synchronously even
if they are transitions, to preserve scroll position if possible. We do
this by entangling the transition lane with the Sync lane.
However, if rendering the transition spawns additional transition
updates (e.g. a setState inside useEffect), there's no reason to render
those synchronously, too. We should use the normal transition behavior.
This fixes an issue where useDeferredValue during a popstate event would
spawn a transition update that was itself also synchronous.
DiffTrain build for [6db7f4209e](https://github.com/facebook/react/commit/6db7f4209e6f32ebde298a0b7451710dd6aa3e19)
### Based on #27509
Revealing a prerendered tree (hidden -> visible) is considered the same
as mounting a brand new tree. So, when an initialValue argument is
passed to useDeferredValue, and it's prerendered inside a hidden tree,
we should first prerender the initial value.
After the initial value has been prerendered, we switch to prerendering
the final one. This is the same sequence that we use when mounting new
visible tree. Depending on how much prerendering work has been finished
by the time the tree is revealed, we may or may not be able to skip all
the way to the final value.
This means we get the benefits of both prerendering and preview states:
if we have enough resources to prerender the whole thing, we do that. If
we don't, we have a preview state to show for immediate feedback.
DiffTrain build for [75c1bd7ee7](https://github.com/facebook/react/commit/75c1bd7ee7e4a87a4dd0f560e157c57957ef823b)
### Based on https://github.com/facebook/react/pull/27505
If a parent render spawns a deferred task with useDeferredValue, but the
parent render suspends, we should not wait for the parent render to
complete before attempting to render the final value.
The reason is that the initialValue argument to useDeferredValue is
meant to represent an immediate preview of the final UI. If we can't
render it "immediately", we might as well skip it and go straight to the
"real" value.
This is an improvement over how a userspace implementation of
useDeferredValue would work, because a userspace implementation would
have to wait for the parent task to commit (useEffect) before spawning
the deferred task, creating a waterfall.
DiffTrain build for [b2a68a65c8](https://github.com/facebook/react/commit/b2a68a65c84b63ac86930d88ae5c84380cbbdeb6)
<!--
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
Changes `before before` to `before` in error messages.
<!--
Explain the **motivation** for making this change. What existing problem
does the pull request solve?
-->
I want to improve error logs
## How did you test this change?
<!--
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.
-->
DiffTrain build for [67cc9ba878](https://github.com/facebook/react/commit/67cc9ba8789335b9da0838a446137c1be62adbcd)
A small refactor to how the lane entanglement mechanism works. We can
now distinguish between the lane that "spawned" a render task (i.e. a
new update) versus the lanes that it's entangled with. Both the update
lane and the entangled lanes will be included while rendering, but by
keeping them separate, we don't lose the original priority.
In practical terms, this means we can now entangle a low priority update
with a higher priority lane while rendering at the lower priority.
To do this, lanes that are entangled at the root are now tracked using
the same variable that we use to track the "base lanes" when revealing a
previously hidden tree — conceptually, they are the same thing. I also
renamed this variable (from subtreeLanes to entangledRenderLanes) to
better reflect how it's used.
My primary motivation is related to useDeferredValue, which I'll address
in a later PR.
DiffTrain build for [309c8ad968](https://github.com/facebook/react/commit/309c8ad9688c491e5b17beb07ab01d65594914ce)
Adds a second argument to useDeferredValue called initialValue:
```js
const value = useDeferredValue(finalValue, initialValue);
```
During the initial render of a component, useDeferredValue will return
initialValue. Once that render finishes, it will spawn an additional
render to switch to finalValue.
This same sequence should occur whenever the hook is hidden and revealed
again, i.e. by a Suspense or Activity, though this part is not yet
implemented.
When initialValue is not provided, useDeferredValue has no effect during
initial render, but during an update, it will remain on the previous
value, then spawn an additional render to switch to the new value. (This
is the same behavior that exists today.)
During SSR, initialValue is always used, if provided.
This feature is currently behind an experimental flag. We plan to ship
it in a non-breaking release.
DiffTrain build for [be67db46b6](https://github.com/facebook/react/commit/be67db46b60d94f9fbefccf2523429af25873e5b)
## Summary
Currently when cloning nodes in Fabric, we reset a node's children on
each clone, and then repeatedly call appendChild to restore the previous
list of children (even if it was quasi-identical to before). This causes
unnecessary invalidation of the layout state in Fabric's ShadowNode data
(which in turn may require additional yoga clones) and extra JSI calls.
This PR adds a feature flag to pass in the children as part of the clone
call, so Fabric always has a complete view of the node that's being
mutated.
This feature flag requires matching changes in the react-native repo:
https://github.com/facebook/react-native/pull/39817
## How did you test this change?
Unit test added demonstrates the new behaviour
```
yarn test -r www-modern ReactFabric-test
yarn test ReactFabric-test.internal
```
Tested a manual sync into React Native and verified core surfaces render
correctly.
DiffTrain build for [151e75a128](https://github.com/facebook/react/commit/151e75a128d0fd436dce365335b96c5686f704d4)
### Based on #27453
If optimistic state is updated, and there's no startTransition on the
stack, there are two likely scenarios.
One possibility is that the optimistic update is triggered by a regular
event handler (e.g. `onSubmit`) instead of an action. This is a mistake
and we will warn.
The other possibility is the optimistic update is inside an async
action, but after an `await`. In this case, we can make it "just work"
by associating the optimistic update with the pending async action.
Technically it's possible that the optimistic update is unrelated to the
pending action, but we don't have a way of knowing this for sure because
browsers currently do not provide a way to track async scope. (The
AsyncContext proposal, if it lands, will solve this in the future.)
However, this is no different than the problem of unrelated transitions
being grouped together — it's not wrong per se, but it's not ideal.
Once AsyncContext starts landing in browsers, we will provide better
warnings in development for these cases.
DiffTrain build for [88d56b8e81](https://github.com/facebook/react/commit/88d56b8e818d0c48eb6642303169c1fadeb99d59)
I found a bug where if an optimistic update causes a component to
rerender, and there are no other state updates during that render, React
bails out without applying the update.
Whenever a hook detects a change, we must mark the component as dirty to
prevent a bailout. We check for changes by comparing the new state to
`hook.memoizedState`. However, when implementing optimistic state
rebasing, I incorrectly reset `hook.memoizedState` to the incoming base
state, even though I only needed to reset `hook.baseState`. This was
just a mistake on my part.
This wasn't caught by the existing tests because usually when the
optimistic state changes, there's also some other state that marks the
component as dirty in the same render.
I fixed the bug and added a regression test.
DiffTrain build for [85c2b519b5](https://github.com/facebook/react/commit/85c2b519b54269811002d26f4f711809ef68f123)