Commit Graph

1310 Commits

Author SHA1 Message Date
huntie 038fe5aafd Root import types from react-native in ReactNativeTypes (#33063)
DiffTrain build for [9518f11856](https://github.com/facebook/react/commit/9518f1185621aecb99fd72385cdb137c6e8bd8fe)
2025-05-09 04:18:34 -07:00
sebmarkbage e9cd841727 Use a shared noop function from shared/noop (#33154)
Stacked on #33150.

We use `noop` functions in a lot of places as place holders. I don't
think there's any real optimizations we get from having separate
instances. This moves them to use a common instance in `shared/noop`.

DiffTrain build for [21fdf308a1](https://github.com/facebook/react/commit/21fdf308a1a01af69c28c00a70086aa1bd4c2411)
2025-05-08 18:40:16 -07:00
jackpope a5a6ecd6f4 Clean up enableSiblingPrerendering flag (#32319)
DiffTrain build for [4ca97e4891](https://github.com/facebook/react/commit/4ca97e4891b6a664b4c3a183f16b81139655ff57)
2025-05-08 17:56:17 -07:00
sebmarkbage 4ab120c3e2 Add plumbing for onDefaultTransitionIndicator (#33150)
This just adds the options at the root and wire it up to the root but it
doesn't do anything yet.

DiffTrain build for [9b79292ae7](https://github.com/facebook/react/commit/9b79292ae7c2980acb531f1dff3cf1ca2d2f40b7)
2025-05-08 17:50:16 -07:00
josephsavona 49d9f3fc49 feat(compiler): Implement constant propagation for template literals (#33139)
New take on #29716

## Summary
Template literals consisting entirely of constant values will be inlined
to a string literal, effectively replacing the backticks with a double
quote.

This is done primarily to make the resulting instruction a string
literal, so it can be processed further in constant propatation. So this
is now correctly simplified to `true`:
```js
`` === "" // now true
`a${1}` === "a1" // now true
```

If a template string literal can only partially be comptime-evaluated,
it is not that useful for dead code elimination or further constant
folding steps and thus, is left as-is in that case. Same is true if the
literal contains an array, object, symbol or function.

## How did you test this change?

See added tests.

DiffTrain build for [ac06829246](https://github.com/facebook/react/commit/ac06829246287751e6b74bd99cd1b39d1aeba06a)
2025-05-08 09:31:02 -07:00
mofeiZ 8bf45a64d3 [compiler][playground][tests] Standardize more pragmas (#33146)
(Almost) all pragmas are now one of the following:
- `@...TestOnly`: custom pragma for test fixtures
- `@<configName>` | `@<configName>:true`: enables with either true or a
default enabled value
- `@<configName>:<json value>`

DiffTrain build for [38ef6550a8](https://github.com/facebook/react/commit/38ef6550a88f7744f5dcd4a3de7af6f13a540be5)
2025-05-08 08:34:54 -07:00
mofeiZ de1368397f [compiler][be] Move test pragma to separate file (#33145)
`Environment.ts` is getting complex so let's separate test / playground
parsing logic from it
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/33145).
* #33146
* __->__ #33145

DiffTrain build for [b629a865fb](https://github.com/facebook/react/commit/b629a865fb18b899d251bf5c3c5ca2580d222720)
2025-05-08 08:32:08 -07:00
mofeiZ fa188d4d3c [compiler][be] repro edge cases for noEmit and module opt-outs (#33144)
see test fixtures
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/33144).
* #33146
* #33145
* __->__ #33144

DiffTrain build for [fbe7bc21b9](https://github.com/facebook/react/commit/fbe7bc21b9aa00afa230132b3f7eee6d2b5c94a7)
2025-05-08 08:24:54 -07:00
hoxyq 312369393b React DevTools 6.1.1 -> 6.1.2 (#33142)
Patch release to mitigate https://github.com/facebook/react/issues/32659

Essentially just 6.1.1 with:
* Restore all Transitions for Tree updates
([eps1lon](https://github.com/eps1lon) in
[#33042](https://github.com/facebook/react/pull/33042))
* Restore "double-click to view owners tree" functionality
([eps1lon](https://github.com/eps1lon) in
[#33039](https://github.com/facebook/react/pull/33039))

DiffTrain build for [557a64795c](https://github.com/facebook/react/commit/557a64795c6b55e32a87c468c9069b05319d3b9b)
2025-05-08 00:08:06 -07:00
jackpope 2222d94322 Add dispatchEvent to fragment instances (#32813)
`fragmentInstance.dispatchEvent(evt)` calls `element.dispatchEvent(evt)`
on the fragment's host parent. This mimics bubbling if the
`fragmentInstance` could receive an event itself.

If the parent is disconnected, there is a dev warning and no event is
dispatched.

DiffTrain build for [8a8df5dbdd](https://github.com/facebook/react/commit/8a8df5dbdd57bf63d5156c1a9cba21ac6106b83d)
2025-05-07 11:08:46 -07:00
josephsavona dd523f1e28 feat(compiler): implement constant folding for unary minus (#33140)
## Summary
`-constant` is represented as a `UnaryExpression` node that is currently
not part of constant folding. If the operand is a constant number, the
node is folded to `constant * -1`. This also coerces `-0` to `0`,
resulting in `0 === -0` being folded to `true`.

## How did you test this change?
See attached tests

DiffTrain build for [946da518eb](https://github.com/facebook/react/commit/946da518eb2d64d808f9204a72e05892d3005f3f)
2025-05-07 10:21:45 -07:00
sebmarkbage 9b0f8d9d05 [Flight] Clarify that location field is a FunctionLocation not a CallSite (#33141)
Follow up to #33136.

This clarifies in the types where the conversion happens from a CallSite
which we use to simulate getting the enclosing line/col to a
FunctionLocation which doesn't represent a CallSite but actually just
the function which only has an enclosing line/col.

DiffTrain build for [a437c99ff7](https://github.com/facebook/react/commit/a437c99ff7a45025367571363653c2ad5db482a7)
2025-05-07 10:10:11 -07:00
jackpope a8615f88be Allow fragment refs to attempt focus/focusLast on nested host children (#33058)
This enables `focus` and `focusLast` methods on FragmentInstances to
search nested host components, depth first. Attempts focus on each child
and bails if one is successful. Previously, only the first level of host
children would attempt focus.

Now if we have an example like

```
component MenuItem() {
  return (<div><a>{...}</a></div>)
}

component Menu() {
  return <Fragment>{items.map(i => <MenuItem i={i} />)}</Fragment>
}
```
We can target focus on the first or last a tag, rather than checking
each wrapping div and then noop.

DiffTrain build for [4206fe4982](https://github.com/facebook/react/commit/4206fe49825787eda57a5d142640a63772ccbf2b)
2025-05-07 09:54:00 -07:00
sebmarkbage 1264bca160 [Flight] Encode enclosing line/column numbers and use it to align the fake function (#33136)
Stacked on #33135.

This encodes the line/column of the enclosing function as part of the
stack traces. When that information is available.

I adjusted the fake function code generation so that the beginning of
the arrow function aligns with these as much as possible.

This ensures that when the browser tries to look up the line/column of
the enclosing function, such as for getting the function name, it gets
the right one. If we can't get the enclosing line/column, then we encode
it at the beginning of the file. This is likely to get a miss in the
source map identifiers, which means that the function name gets
extracted from the runtime name instead which is better.

Another thing where this is used is the in the Performance Track.
Ideally that would be fixed by
https://issues.chromium.org/u/1/issues/415968771 but the enclosing
information is useful for other things like the function name resolution
anyway.

We can also use this for the "View source for this element" in React
DevTools.

DiffTrain build for [4a702865dd](https://github.com/facebook/react/commit/4a702865dd0c5849c1b454091560c3ef26121611)
2025-05-07 09:49:02 -07:00
sebmarkbage bd2fd378a8 [Flight] Parse Stack Trace from Structured CallSite if available (#33135)
This is first step to include more enclosing line/column in the parsed
data.

We install our own `prepareStackTrace` to collect structured callsite
data and only fall back to parsing the string if it was already
evaluated or if `prepareStackTrace` doesn't work in this environment.

We still mirror the default V8 format for encoding the function name
part. A lot of this is covered by tests already.

DiffTrain build for [0ff1d13b80](https://github.com/facebook/react/commit/0ff1d13b8055c801d8b9b6779958c09fd0dc63e0)
2025-05-07 08:50:43 -07:00
hoxyq 93ff544b29 [DevTools] Use Popover API for TraceUpdates highlighting (#32614)
## Summary

When using React DevTools to highlight component updates, the highlights
would sometimes appear behind elements that use the browser's
[top-layer](https://developer.mozilla.org/en-US/docs/Glossary/Top_layer)
(such as `<dialog>` elements or components using the Popover API). This
made it difficult to see which components were updating when they were
inside or behind top-layer elements.

This PR fixes the issue by using the Popover API to ensure that
highlighting appears on top of all content, including elements in the
top-layer. The implementation maintains backward compatibility with
browsers that don't support the Popover API.

## How did you test this change?

I tested this change in the following ways:

1. Manually tested in Chrome (which supports the Popover API) with:
- Created a test application with React components inside `<dialog>`
elements and custom elements using the Popover API
- Verified that component highlighting appears above these elements when
they update
- Confirmed that highlighting displays correctly for nested components
within top-layer elements

2. Verified backward compatibility:
- Tested in browsers without Popover API support to ensure fallback
behavior works correctly
- Confirmed that no errors occur and highlighting still functions as
before

3. Ran the React DevTools test suite:
   - All tests pass successfully
   - No regressions were introduced

[demo-page](https://devtools-toplayer-demo.vercel.app/)
[demo-repo](https://github.com/yongsk0066/devtools-toplayer-demo)

### AS-IS

https://github.com/user-attachments/assets/dc2e1281-969f-4f61-82c3-480153916969

### TO-BE

https://github.com/user-attachments/assets/dd52ce35-816c-42f0-819b-0d5d0a8a21e5

DiffTrain build for [53c9f81049](https://github.com/facebook/react/commit/53c9f81049b4440a02b5ed3edb128516821c0279)
2025-05-07 07:55:29 -07:00
jackpope 8b54080b18 Add compareDocumentPosition to fragment instances (#32722)
This adds `compareDocumentPosition(otherNode)` to fragment instances.

The semantics implemented are meant to match typical element
positioning, with some fragment specifics. See the unit tests for all
expectations.

- An element preceding a fragment is `Node.DOCUMENT_POSITION_PRECEDING`
- An element after a fragment is `Node.DOCUMENT_POSITION_FOLLOWING`
- An element containing the fragment is
`Node.DOCUMENT_POSITION_PRECEDING` and
`Node.DOCUMENT_POSITION_CONTAINING`
- An element within the fragment is
`Node.DOCUMENT_POSITION_CONTAINED_BY`
- An element compared against an empty fragment will result in
`Node.DOCUMENT_POSITION_DISCONNECTED` and
`Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC`

Since we assume a fragment instances target children are DOM siblings
and we want to compare the full fragment as a pseudo container, we can
compare against the first target child outside of handling the special
cases (empty fragments and contained elements).

DiffTrain build for [e5a8de81e5](https://github.com/facebook/react/commit/e5a8de81e57181692d33ce916dfd6aa23638ec92)
2025-05-06 10:07:58 -07:00
jorge-cab 6cf0f2acf1 [mcp] Add proper web-vitals metric collection (#33109)
Multiple things here:
- Improve the mean calculation for metrics so we don't report 0 when
web-vitals fail to be retrieved
- improve ui chaos monkey to use puppeteer APIs since only those trigger
INP/CLS metrics since we need emulated mouse clicks
- Add logic to navigate to a temp page after render since some
web-vitals metrics are only calculated when the page is backgrounded
- Some readability improvements

DiffTrain build for [7a2c7045ae](https://github.com/facebook/react/commit/7a2c7045aed222b1ece44a18db6326f2f10c89e3)
2025-05-06 08:58:05 -07:00
sebmarkbage f2955dbb6f Remove useId semantics from View Transition name generation (#33094)
Originally I thought it was important that SSR used the same View
Transition name as the client so that the Fizz runtime could emit those
names and then the client could pick up and take over. However, I no
longer believe that approach is feasible. Instead, the names can be
generated only during that particular animation.

Therefore we can simplify the auto name assignment to not have to
consider the hydration.

DiffTrain build for [845d93742f](https://github.com/facebook/react/commit/845d93742fb090e7a35abea409a55e2a14613255)
2025-05-06 07:39:53 -07:00
sebmarkbage a42f581a93 [Fiber] Replay events between commits (#33130)
Stacked on #33129. Flagged behind `enableHydrationChangeEvent`.

If you type into a controlled input before hydration and something else
rerenders like a setState in an effect, then the controlled input will
reset to whatever React thought it was. Even with event replaying that
this is stacked on, if the second render happens before event replaying
has fired in a separate task.

We don't want to flush inside the commit phase because then things like
flushSync in these events wouldn't work since they're inside the commit
stack.

This flushes all event replaying between renders by flushing it at the
end of `flushSpawned` work. We've already committed at that point and is
about to either do subsequent renders or yield to event loop for passive
effects which could have these events fired anyway. This just ensures
that they've already happened by the time subsequent renders fire. This
means that there's now a type of event that fire between sync render
passes.

DiffTrain build for [54a50729cc](https://github.com/facebook/react/commit/54a50729cc47a884c2110d7c59dd5f850748e142)
2025-05-05 21:30:15 -07:00
sebmarkbage b9cbc6c4d6 [Fiber] Replay onChange Events if input/textarea/select has changed before hydration (#33129)
This fixes a long standing issue that controlled inputs gets out of sync
with the browser state if it's changed before we hydrate.

This resolves the issue by replaying the change events (click, input and
change) if the value has changed by the time we commit the hydration.
That way you can reflect the new value in state to bring it in sync. It
does this whether controlled or uncontrolled.

The idea is that this should be ok to replay because it's similar to the
continuous events in that it doesn't replay a sequence but only reflects
the current state of the tree.

Since this is a breaking change I added it behind
`enableHydrationChangeEvent` flag.

There is still an additional issue remaining that I intend to address in
a follow up. If a `useLayoutEffect` triggers an sync rerender on
hydration (always a bad idea) then that can rerender before we have had
a chance to replay the change events. If that renders through a input
then that input will always override the browser value with the
controlled value. Which will reset it before we've had a change to
update to the new value.

DiffTrain build for [587cb8f896](https://github.com/facebook/react/commit/587cb8f8967866139bbfdbae3f519cb37e68a054)
2025-05-05 21:17:22 -07:00
mattcarrollcode a22ebb7322 Add test for multiple form submissions (#33059)
Test for #30041 and #33055

DiffTrain build for [79586c7eb6](https://github.com/facebook/react/commit/79586c7eb626c6b9362c308a54c9ee5b66e640e5)
2025-05-05 14:54:31 -07:00
jackpope a4ffeb264d Ship enableFabricCompleteRootInCommitPhase (#33064)
This was shipped internally. Cleaning up the flag.

DiffTrain build for [edf550b679](https://github.com/facebook/react/commit/edf550b67936f2c62534ad5549bf580a4f581bd8)
2025-05-05 10:43:14 -07:00
eps1lon 59155fde4b [Flight] Prevent serialized size leaking across requests (#33121)
DiffTrain build for [b9cfa0d308](https://github.com/facebook/react/commit/b9cfa0d3083f80bdd11ba76a55aa08fa659b7359)
2025-05-05 09:37:30 -07:00
mofeiZ fbdaa3f702 [compiler][repro] Nested fbt test fixture (#32779)
Ideally we should detect and bail out on this case to avoid babel build
failures.

DiffTrain build for [c129c2424b](https://github.com/facebook/react/commit/c129c2424b662a371865a0145c562a1cf934b023)
2025-05-05 08:59:49 -07:00
mofeiZ 45b4735773 [compiler][bugfix] Bail out when a memo block declares hoisted fns (#32765)
Note that bailing out adds false positives for hoisted functions whose
only references are within other functions. For example, this rewrite
would be safe.
```js
// source program
  function foo() {
    return bar();
  }
  function bar() {
    return 42;
  }

// compiler output
let bar;
if (/* deps changed */) {
  function foo() {
    return bar();
  }
  bar = function bar() {
    return 42;
  }
}
```
These false positives are difficult to detect because any maybe-call of
foo before the definition of bar would be invalid.

Instead of bailing out, we should rewrite hoisted function declarations
to the following form.
```js
let bar$0;
if (/* deps changed */) {
  // All references within the declaring memo block
  // or before the function declaration should use
  // the original identifier `bar`
  function foo() {
    return bar();
  }
  function bar() {
    return 42;
  }
  bar$0 = bar;
}
// All references after the declaring memo block
// or after the function declaration should use
// the rewritten declaration `bar$0`
```

DiffTrain build for [0c1575cee8](https://github.com/facebook/react/commit/0c1575cee8a78dd097edcafc307522ad000e372c)
2025-05-05 08:52:26 -07:00
eps1lon d45b272868 [eslint-plugin-react-hooks] update doc url for rules of hooks (#33118)
DiffTrain build for [3ec88e797f](https://github.com/facebook/react/commit/3ec88e797f7352c87cb79292b02fdfc53050133f)
2025-05-05 08:44:00 -07:00
eps1lon 16e2c886df [Flight] Use valid CSS selectors in useId format (#33099)
DiffTrain build for [0ca8420f9d](https://github.com/facebook/react/commit/0ca8420f9d051285c452a590ac4a4c9476406bef)
2025-05-04 04:56:36 -07:00
josephsavona d3ae62070c [compiler] Validate against mutable functions being frozen
This revisits a validation I built a while ago, trying to make it more strict this time to ensure that it's high-signal.

We detect function expressions which are *known* mutable — they definitely can modify a variable defined outside of the function expression itself (modulo control flow). This uses types to look for known Store and Mutate effects only, and disregards mutations of effects. Any such function passed to a location with a Freeze effect is reported as a validation error.

This is behind a flag and disabled by default. If folks agree this makes sense to revisit, i'll test out internally and we can consider enabling by default.

ghstack-source-id: 075a731444
Pull Request resolved: https://github.com/facebook/react/pull/33079

DiffTrain build for [0db8db178c](https://github.com/facebook/react/commit/0db8db178c1521f979535bdba32bf9db9f47ca05)
2025-05-02 17:22:33 -07:00
josephsavona 31e777b1b6 [compiler] ValidatePreservedManualMemoization reports detailed errors
This pass didn't previously report the precise difference btw inferred/manual dependencies unless a debug flag was set. But the error message is really good (nice job mofeiz): the only catch is that in theory the inferred dep could be a temporary that can't trivially be reported to the user.

But the messages are really useful for quickly verifying why the compiler couldn't preserve memoization. So here we switch to outputting a detailed message about the discrepancy btw inferred/manual deps so long as the inferred dep root is a named variable. I also slightly adjusted the message to handle the case where there is no diagnostic, which can occur if there were no manual deps but the compiler inferred a dependency.

ghstack-source-id: 534f6f1fec
Pull Request resolved: https://github.com/facebook/react/pull/33095

DiffTrain build for [73d7e816b7](https://github.com/facebook/react/commit/73d7e816b7746c700ab843964aaf11c17351fac1)
2025-05-02 17:15:46 -07:00
josephsavona 4c4b5dcb6f [compiler] Fix for string attribute values with emoji
If a JSX attribute value is a string that contains unicode or other characters that need special escaping, we wrap the attribute value in an expression container. However, our unicode to detect this only handled the basic unicode character plane, not the "astral" plane which includes emojis.

This PR updates the regex to detect such extended characters and also use an expression container.

ghstack-source-id: 6d9c8e4dd2
Pull Request resolved: https://github.com/facebook/react/pull/33096

DiffTrain build for [ac2cae5245](https://github.com/facebook/react/commit/ac2cae524576b8091a6d78d9ab05627053949df1)
2025-05-02 17:14:24 -07:00
kassens e088016fbd [eslint-plugin-react-hooks] move eslint plugin once again (#33110)
DiffTrain build for [66de8e5a99](https://github.com/facebook/react/commit/66de8e5a9975a4b53734ebed8a1c1f07892426a8)
2025-05-02 15:21:33 -07:00
poteto a405810329 [mcp] Prompt improvements for smarter tool composition (#33108)
Our runtime results are still bogus, but so far this tweak let's the llm
use the tools a little more intelligently.

example:
---

```js
import React from 'react';

function App() {
  const [count, setCount] = React.useState(0);
  const [data, setData] = React.useState([]);

  React.useEffect(() => {
    const processData = () => {
      console.log("Processing data...");
      const newData = [];
      for (let i = 0; i < 1000000000; i++) {
        newData.push({ id: i, value: Math.random() * count });
      }
      return newData;
    };

    const processedData = processData();
    setData(processedData);
  }, [count]);

  return (
    <div>
      <p>Count: {count}</p>
      <p>Data Length: {data.length}</p>
      <ul>
        {data.slice(0, 5).map((item) => (
          <li key={item.id}>Item {item.id}: {item.value.toFixed(2)}</li>
        ))}
      </ul>
    </div>
  );
};
```
why is this component slow? use the react tools to figure this out.

> I'll analyze why this component is slow using the React tools. Let's
first evaluate the performance of the original code.
>
[review-react-runtime ...]
>
> The performance measurement tool timed out, which is a strong
indication of just how severe the performance issue is in this
component. Let's now try to compile the code to see if React Compiler
can identify any issues:
>
[compile...]
>
> Now I understand the issue. Let's analyze why this component > is
extremely slow:
> Main Performance Issues:
>
> Massive Data Processing: The component is trying to create an array
with a billion (1,000,000,000) objects in the processData function. This
is an enormous amount of data that will:
>
> Consume massive amounts of memory
> Take an extremely long time to process
> Likely crash the browser
>
>
> Unnecessary Recalculation: The effect depends on [count], meaning
every time the count changes, it will reprocess this enormous dataset.
> Inefficient Data Handling: Even though only 5 items are displayed, the
component processes a billion items.
>
> Let's fix these issues:
>
[compile...]
>
> Now let's check if our modified code performs better:
>
[review-react-runtime...]
>
> Excellent! The performance has dramatically improved. Now let's check
the React documentation to make sure we're following the best practices:
>
[query-react-dev-docs...]

(hit the maximum length conversation limit because i'm on a free plan)

DiffTrain build for [26ecc98a00](https://github.com/facebook/react/commit/26ecc98a0014700524e78d938e3654c73213cf3b)
2025-05-02 14:58:11 -07:00
kassens ee8cbecf82 [eslint-plugin-react-hooks] another CI update... (#33107)
We currently created a nested directory, this should remove that.

See:

https://github.com/facebook/react/tree/builds/facebook-fbsource/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/eslint-plugin-react-hooks/eslint-plugin-react-hooks

DiffTrain build for [f0ca53d133](https://github.com/facebook/react/commit/f0ca53d1337780ccfd49c132170d378c789cb463)
2025-05-02 14:12:21 -07:00
poteto 703c496bfd [mcp] Fix unresolved imports (#33105)
We need to explicitly import the modules so they'll be inlined correctly
into the bundle.

DiffTrain build for [e39b380a21](https://github.com/facebook/react/commit/e39b380a21aa4ef48d5880aa2c800ec5b1b044bd)
2025-05-02 14:01:14 -07:00
kassens 6a15b09f98 Add missing copyright header (#33106)
This made the build fail since there was no file header comment.

DiffTrain build for [9de0304ad7](https://github.com/facebook/react/commit/9de0304ad72bc3f8a77d2d84efa530b8051d1c15)
2025-05-02 13:59:14 -07:00
sebmarkbage 7f00c48042 [Fizz] Add "Queued" Status to SSR:ed Suspense Boundaries (#33087)
Stacked on #33076.

This fixes a bug where we used the "complete" status but the
DOMContentLoaded event. This checks for not "loading" instead.

We also add a new status where the boundary has been marked as complete
by the server but has not yet flushed either due to being throttled,
suspended on CSS or animating.

DiffTrain build for [0ed6ceb9f6](https://github.com/facebook/react/commit/0ed6ceb9f6c19f28c504cf46193cef40166a61f6)
2025-05-01 13:18:31 -07:00
jackpope e4b4f1304c Add Fragment Refs to Fabric with intersection observer support (#33056)
Adds Fragment Ref support to RN through the Fabric config, starting with
`observeUsing`/`unobserveUsing`. This is mostly a copy from the
implementation on DOM, and some of it can likely be shared in the future
but keeping it separate for now and we can refactor as we add more
features.

Added a basic test with Fabric, but testing specific methods requires so
much mocking that it doesn't seem valuable here.

I built Fabric and ran on the Catalyst app internally to test with
intersection observers end to end.

DiffTrain build for [408d055a3b](https://github.com/facebook/react/commit/408d055a3b89794088130ed39bf42ca540766275)
2025-04-30 07:55:26 -07:00
sebmarkbage f1021c7e9f Hack to recover from reading the wrong Fiber (#33055)
`requestFormReset` incorrectly tries to get the current dispatch queue
from the Fiber. However, the Fiber might be the workInProgress which is
an inconsistent state.

This hack just tries the other Fiber if it detects one of the known
inconsistent states but there can be more.

Really we should stash the dispatch queue somewhere stateful which is
effectively what `setState` does by binding it to the closure.

DiffTrain build for [88b9767404](https://github.com/facebook/react/commit/88b976740467f9dfabae03c79a8eff9033c35050)
2025-04-29 13:16:55 -07:00
javache 63af232d46 [react-native] Pull up enableFastAddPropertiesInDiffing check (#33043)
## Summary

We don't need the isArray check for this experiment, as
`fastAddProperties` already does the same. Also renaming
slowAddProperties to make it clearer we can fully remove this codepath
once fastAddProperties is fully rolled out.

## How did you test this change?

```
yarn test packages/react-native-renderer -r=xplat --variant=true
```

DiffTrain build for [0038c501a3](https://github.com/facebook/react/commit/0038c501a307e5ddc0cb80027e55740ddda09520)
2025-04-29 03:16:29 -07:00
sebmarkbage 520902d9c2 Implement Partial Hydration for Activity (#32863)
Stacked on #32862 and #32842.

This means that Activity boundaries now act as boundaries which can have
their effects mounted independently. Just like Suspense boundaries, we
hydrate the outer content first and then start hydrating the content in
an Offscreen lane. Flowing props or interacting with the content
increases the priority just like Suspense boundaries.

This skips emitting even the comments for `<Activity mode="hidden">` so
we don't hydrate those. Instead those are deferred to a later client
render.

The implementation are just forked copies of the SuspenseComponent
branches and then carefully going through each line and tweaking it.

The main interesting bit is that, unlike Suspense, Activity boundaries
don't have fallbacks so all those branches where you might commit a
suspended tree disappears. Instead, if something suspends while
hydration, we can just leave the dehydrated content in place. However,
if something does suspend during client rendering then it should bubble
up to the parent. Therefore, we have to be careful to only
pushSuspenseHandler when hydrating. That's really the main difference.

This just uses the existing basic Activity tests but I've started work
on port all of the applicable Suspense tests in SelectiveHydration-test
and PartialHydration-test to Activity versions.

DiffTrain build for [3ef31d196a](https://github.com/facebook/react/commit/3ef31d196a83e45d4c70b300a265a9c657c386b4)
2025-04-22 18:07:47 -07:00
sebmarkbage 1ed5cd364a Implement ActivityInstance in FiberConfigDOM (#32842)
Stacked on #32851 and #32900.

This implements the equivalent Configs for ActivityInstance as we have
for SuspenseInstance. These can be implemented as comments but they
don't have to be and can be implemented differently in the renderer.

This seems like a lot duplication but it's actually ends mostly just
calling the same methods underneath and the wrappers compiles out.

This doesn't leave the Activity dehydrated yet. It just hydrates into it
immediately.

DiffTrain build for [17f88c80ed](https://github.com/facebook/react/commit/17f88c80ed20b4e5f21255d9e1268542a2fbc1bd)
2025-04-22 16:50:48 -07:00
sebmarkbage b480230f1b Set hidden Offscreen to the shellBoundary regardless of previous state (#32844)
I think this was probably just copy-paste from the Suspense path.

It shouldn't matter what the previous state of an Offscreen boundary
was. What matters is that it's now hidden and therefore if it suspends,
we can just leave it as is without the tree becoming inconsistent.

DiffTrain build for [3fbd6b7b50](https://github.com/facebook/react/commit/3fbd6b7b50e3a174883633695586b892249e5635)
2025-04-22 16:45:55 -07:00
sebmarkbage f75bdfdeac Hide/unhide the content of dehydrated suspense boundaries if they resuspend (#32900)
Found this bug while working on Activity. There's a weird edge case when
a dehydrated Suspense boundary is a direct child of another Suspense
boundary which is hydrated but then it resuspends without forcing the
inner one to hydrate/delete.

It used to just leave that in place because hiding/unhiding didn't deal
with dehydrated fragments.

Not sure this is really worth fixing.

DiffTrain build for [ebf7318e87](https://github.com/facebook/react/commit/ebf7318e87cf2e10b6bd9a6bb0ad8bf6f6186f80)
2025-04-22 16:35:26 -07:00
sebmarkbage 6c77e921d6 Don't try to hydrate a hidden Offscreen tree (#32862)
I found a bug even before the Activity hydration stuff.

If we're hydrating an Offscreen boundary in its "hidden" state it won't
have any content to hydrate so will trigger hydration errors (which are
then eaten by the Offscreen boundary itself). Leaving it not prewarmed.

This doesn't happen in the simple case because we'd be hydrating at a
higher priority than Offscreen at the root, and those are deferred to
Offscreen by not having higher priority. However, we've hydrating at the
Offscreen priority, which we do inside Suspense boundaries, then it
tries to hydrate against an empty set.

I ended up moving this to the Activity boundary in a future PR since
it's the SSR side that decided where to not render something and it only
has a concept of Activity, no Offscreen.

https://github.com/facebook/react/pull/32863/commits/1dc05a5e2222e18fc3a2062ee1bd957109e21344#diff-d5166797ebbc5b646a49e6a06a049330ca617985d7a6edf3ad1641b43fde1ddfR1111

DiffTrain build for [b04254fdce](https://github.com/facebook/react/commit/b04254fdcee30871760301f34236ee0dfadf86ab)
2025-04-15 14:49:57 -07:00
sebmarkbage a0c6870f0c Warn if you pass a hidden prop to Activity (#32916)
Since `hidden` is a prop on arbitrary DOM elements it's a common mistake
to think that it would also work that way on `<Activity>` but it
doesn't. In fact, we even had this mistakes in our own tests.

Maybe there's an argument that we should actually just support it but we
also have more modes planned.

So this adds a warning. It should also already be covered by TypeScript.

DiffTrain build for [539bbdbd86](https://github.com/facebook/react/commit/539bbdbd86d9cd342aabde4cb08e398751789103)
2025-04-15 14:23:51 -07:00
sebmarkbage 609b3ae8de Try not. Do... or do not. Hydrate Suspense Boundaries. (#32851)
Assertively claim a SuspenseInstance. We already know we're hydrating.

If there's no match, it throws anyway. So there's no other code path.

DiffTrain build for [961b625ab5](https://github.com/facebook/react/commit/961b625ab5d180180e836e0c7b221789f0ee336b)
2025-04-11 07:58:07 -07:00
sebmarkbage 0e2734eb2f Emit Preamble Contribution inline instead of the end of a boundary (#32850)
This lets us write them early in the render phase.

This should be safe because even if we write them deeply, then they
still can't be wrapped by a element because then they'd no longer be in
the document scope anymore. They end up flat in the body and so when we
search the content we'll discover them.

DiffTrain build for [8a3c5e1a8d](https://github.com/facebook/react/commit/8a3c5e1a8d1d89a68ca36c6959c1f253710f6cef)
2025-04-10 16:47:41 -07:00
rubennorte 3aee0d9b2a [RN] Map Fabric priorities to reconciler priorities correctly (#32847)
## Summary

This fixes how we map priorities between Fabric and the React
reconciler. At the moment, we're only considering default and discrete
priorities, when there's a larger range of priorities available.

In Fabric, we'll test supporting additional priorities soon. For that
test to do something useful, we need the new priorities to be mapped to
reconciler priorities correctly, which is what this change is done.

> [!IMPORTANT]
> At the moment, this is a no-op because Fabric is only reporting
default and discrete event priorities.

## How did you test this change?

Will test e2e on React Native on top of
https://github.com/facebook/react-native/pull/50627

The changes are gated in React Native, so we'll use that feature flag to
test this.

DiffTrain build for [5e9b48778c](https://github.com/facebook/react/commit/5e9b48778c83dd8b2c63966db3e23abefebe910c)
2025-04-10 09:40:48 -07:00
sebmarkbage 0a20a318f6 Move Built-in Props Types to React Types (#32841)
Stacked on #32838.

We don't always type the Props of built-ins. This adds typing for most
of the built-ins.

When we did type them, we used to put it in the `ReactFiber...Component`
files but any public API like this can be implemented in other renderers
too such as Fizz. So I moved them to `shared/ReactTypes` which is where
we put other public API types (that are not already built-in to Flow).
That way Fizz can import them and assert properly when it accesses the
props.

DiffTrain build for [c44e4a2505](https://github.com/facebook/react/commit/c44e4a250557e53b120e40db8b01fb5fd93f1e35)
2025-04-09 19:52:23 -07:00