Commit Graph

476 Commits

Author SHA1 Message Date
Jan Kassens
21129d34a5 Upgrade flow to 0.235.0 (#30118)
See [Flow
changelog](https://github.com/facebook/flow/blob/main/Changelog.md) for
changes in this version.
2024-07-08 14:11:11 -04:00
Jan Kassens
8416ebee38 Update ReactFabric-test.internal to concurrent root (#30103) 2024-06-26 16:04:38 -04:00
Jan Kassens
7045700a6d Run ReactFabric-test.internal.js in xplat variant (#30101)
The explicit mock override in this test was causing it to always run as
native-oss instead of also as xplat. This moves the test to use `//
@gate persistent` instead to run it in all persistent configs.
2024-06-26 12:51:46 -04:00
Jan Kassens
b565373afd lint: enable reportUnusedDisableDirectives and remove unused suppressions (#28721)
This enables linting against unused suppressions and removes the ones
that were unused.
2024-06-21 12:24:32 -04:00
Eric Rozell
3154ec8a38 Use a constant HostContext in prod builds for Fabric renderer (#29888)
<!--
  Thanks for submitting a pull request!
We appreciate you spending the time to work on these changes. Please
provide enough information so that others can review your pull request.
The three fields below are mandatory.

Before submitting a pull request, please make sure the following is
done:

1. Fork [the repository](https://github.com/facebook/react) and create
your branch from `main`.
  2. Run `yarn` in the repository root.
3. If you've fixed a bug or added code that should be tested, add tests!
4. Ensure the test suite passes (`yarn test`). Tip: `yarn test --watch
TestName` is helpful in development.
5. Run `yarn test --prod` to test in the production environment. It
supports the same options as `yarn test`.
6. If you need a debugger, run `yarn test --debug --watch TestName`,
open `chrome://inspect`, and press "Inspect".
7. Format your code with
[prettier](https://github.com/prettier/prettier) (`yarn prettier`).
8. Make sure your code lints (`yarn lint`). Tip: `yarn linc` to only
check changed files.
  9. Run the [Flow](https://flowtype.org/) type checks (`yarn flow`).
  10. If you haven't already, complete the CLA.

Learn more about contributing:
https://reactjs.org/docs/how-to-contribute.html
-->

## Summary

<!--
Explain the **motivation** for making this change. What existing problem
does the pull request solve?
-->

In the Fabric renderer in React Native, we only use the HostContext to
issue soft errors in __DEV__ bundles when attempting to add a raw text
child to a node that may not support them. Moving the logic to set this
context to __DEV__ bundles only unblocks more expensive methods for
resolving whether a parent context supports raw text children, like
resolving this information from `getViewConfigForType`.

## 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.
-->

yarn test (--prod)
2024-06-14 13:37:19 -04:00
Sebastian Markbåge
195d5bb99e Execute event handlers in the context of the instance that it's associated with (#29876)
That way we get owner stacks (native or otherwise) for `console.error`
or `console.warn` inside of them.

Since the `reportError` is also called within this context, we also get
them for errors thrown within event listeners. You'll also be able to
observe this in in the `error` event. Similar to how `onUncaughtError`
is in the scope of the instance that errored - even though
`onUncaughtError` doesn't kick in for event listeners.

Chrome (from console.createTask):

<img width="306" alt="Screenshot 2024-06-12 at 2 08 19 PM"
src="https://github.com/facebook/react/assets/63648/34cd9d57-0df4-44df-a470-e89a5dd1b07d">

<img width="302" alt="Screenshot 2024-06-12 at 2 03 32 PM"
src="https://github.com/facebook/react/assets/63648/678117b1-e03a-47d4-9989-8350212c8135">

Firefox (from React DevTools):

<img width="493" alt="Screenshot 2024-06-12 at 2 05 01 PM"
src="https://github.com/facebook/react/assets/63648/94ca224d-354a-4ec8-a886-5740bcb418e5">

(This is the parent stack since React DevTools doesn't just yet print
owner stack.)

(Firefox doesn't print the component stack for uncaught since we don't
add component stacks for "error" events from React DevTools - just
console.error. Perhaps an oversight.)

If we didn't have the synthetic event system this would kind of just
work natively in Chrome because we have this task active when we attach
the event listeners to the DOM node and async stacks just follow along
that way. In fact, if you attach a manual listener in useEffect you get
this same effect. It's just because we use event delegation that this
doesn't work.

However, if we did get rid of the synthetic event system we'd likely
still want to add a wrapper on the DOM node to set our internal current
owner so that the non-native part of the system still can observe the
active instance. That wouldn't work with manually attached listeners
though.
2024-06-12 16:15:22 -04:00
Sebastian Markbåge
2774208039 Remove Warning: prefix and toString on console Arguments (#29839)
Basically make `console.error` and `console.warn` behave like normal -
when a component stack isn't appended. I need this because I need to be
able to print rich logs with the component stack option and to be able
to disable instrumentation completely in `console.createTask`
environments that don't need it.

Currently we can't print logs with richer objects because they're
toString:ed first. In practice, pretty much all arguments we log are
already toString:ed so it's not necessary anyway. Some might be like a
number. So it would only be a problem if some environment can't handle
proper consoles but then it's up to that environment to toString it
before logging.

The `Warning: ` prefix is historic and is both noisy and confusing. It's
mostly unnecessary since the UI surrounding `console.error` and
`console.warn` tend to have visual treatment around it anyway. However,
it's actively misleading when `console.error` gets prefixed with a
Warning that we consider an error level. There's an argument to be made
that some of our `console.error` don't make the bar for an error but
then the argument is to downgrade each of those to `console.warn` - not
to brand all our actual error logging with `Warning: `.

Apparently something needs to change in React Native before landing this
because it depends on the prefix somehow which probably doesn't make
sense already.
2024-06-10 18:41:56 -04:00
Ricky
d172bdaf95 Add jest lint rules (#29760)
## Overview

Updates `eslint-plugin-jest` and enables the recommended rules with some
turned off that are unhelpful.

The main motivations is:
a) we have a few duplicated tests, which this found an I deleted 
b) making sure we don't accidentally commit skipped tests
2024-06-10 14:31:37 -04:00
Ricky
6b35ff766a Move @generated from build to sync (#29799)
## Overview

Reverts https://github.com/facebook/react/pull/26616 and implements the
suggested way instead.

This change in #26616 broken the internal sync command, which now
results in duplicated `@generated` headers. It also makes it harder to
detect changes during the diff train sync. Instead, we will check for
changes, and if there are changes sign the files and commit them to the
sync branch.

## Strategy

The new sync strategy accounts for the generated headers during the
sync:
- **Revert Version**: Revert the version strings
- **Revert @generated**: Re-sign the files (will be the same hash as
before if unchanged)
- **Check**: Check if there are changes **if not, skip**
- **Re-apply Version**: Now add back the new version string
- **Re-sign @generated**: And re-generate the headers

Then commit to branch. This ensures that if there are no changes, we'll
skip.

---------

Co-authored-by: Timothy Yung <yungsters@gmail.com>
2024-06-10 10:16:40 -04:00
Dmytro Rykun
eb259b5d3b Add enableShallowPropDiffing feature flag (#29664)
## Summary

We currently do deep diffing for object props, and also use custom
differs, if they are defined, for props with custom attribute config.

The idea is to simply do a `===` comparison instead of all that work. We
will do less computation on the JS side, but send more data to native.

The hypothesis is that this change should be neutral in terms of
performance. If that's the case, we'll be able to get rid of custom
differs, and be one step closer to deleting view configs.

This PR adds the `enableShallowPropDiffing` feature flag to support this
experiment.

## How did you test this change?

With `enableShallowPropDiffing` hardcoded to `true`:
```
yarn test packages/react-native-renderer
```
This fails on the following test cases:
- should use the diff attribute
- should do deep diffs of Objects by default
- should skip deeply-nested changed functions

Which makes sense with this change. These test cases should be deleted
if the experiment is shipped.
2024-06-05 15:07:58 +01:00
Ricky
eabb681535 Add xplat test variants (#29734)
## Overview

We didn't have any tests that ran in persistent mode with the xplat
feature flags (for either variant).

As a result, invalid test gating like in
https://github.com/facebook/react/pull/29664 were not caught.

This PR adds test flavors for `ReactFeatureFlag-native-fb.js` in both
variants.
2024-06-04 13:07:29 -04:00
Dmytro Rykun
51dd09631a Add tests for ReactNativeAttributePayloadFabric.js (#29608)
## Summary

This PR add tests for `ReactNativeAttributePayloadFabric.js`.

It introduces `ReactNativeAttributePayloadFabric-test.internal.js`,
which is a copy-paste of `ReactNativeAttributePayload-test.internal.js`.

On top of that, there is a bunch of new test cases for the
`ReactNativeAttributePayloadFabric.create` function.

## How did you test this change?

```
yarn test packages/react-native-renderer
```
2024-05-30 10:24:00 +01:00
Timothy Yung
3b29ed1638 Fix "findNodeHandle inside its render()" False Positive Warning (#29627)
This was missed in https://github.com/facebook/react/pull/29038 when
unifying the "owner" abstractions, causing `findNodeHandle` to warn even
outside of `render()` invocations.
2024-05-28 20:36:41 -07:00
Andrew Clark
681a4aa810 Throw if React and React DOM versions don't match (#29236)
Throw an error during module initialization if the version of the
"react-dom" package does not match the version of "react".

We used to be more relaxed about this, because the "react" package
changed so infrequently. However, we now have many more features that
rely on an internal protocol between the two packages, including Hooks,
Float, and the compiler runtime. So it's important that both packages
are versioned in lockstep.

Before this change, a version mismatch would often result in a cryptic
internal error with no indication of the root cause.

Instead, we will now compare the versions during module initialization
and immediately throw an error to catch mistakes as early as possible
and provide a clear error message.
2024-05-28 14:06:30 -04:00
Sebastian Markbåge
2e3e6a9b1c Unify ReactFiberCurrentOwner and ReactCurrentFiber (#29038)
We previously had two slightly different concepts for "current fiber".

There's the "owner" which is set inside of class components in prod if
string refs are enabled, and sometimes inside function components in DEV
but not other contexts.

Then we have the "current fiber" which is only set in DEV for various
warnings but is enabled in a bunch of contexts.

This unifies them into a single "current fiber".

The concept of string refs shouldn't really exist so this should really
be a DEV only concept. In the meantime, this sets the current fiber
inside class render only in prod, however, in DEV it's now enabled in
more contexts which can affect the string refs. That was already the
case that a string ref in a Function component was only connecting to
the owner in prod. Any string ref associated with any non-class won't
work regardless so that's not an issue. The practical change here is
that an element with a string ref created inside a life-cycle associated
with a class will work in DEV but not in prod. Since we need the current
fiber to be available in more contexts in DEV for the debugging
purposes. That wouldn't affect any old code since it would have a broken
ref anyway. New code shouldn't use string refs anyway.

The other implication is that "owner" doesn't necessarily mean
"rendering" since we need the "owner" to track other debug information
like stacks - in other contexts like useEffect, life cycles, etc.
Internally we have a separate `isRendering` flag that actually means
we're rendering but even that is a very overloaded concept. So anything
that uses "owner" to imply rendering might be wrong with this change.

This is a first step to a larger refactor for tracking current rendering
information.

---------

Co-authored-by: Sebastian Silbermann <silbermann.sebastian@gmail.com>
2024-05-23 12:25:23 -04:00
Josh Story
217b2ccf16 [Fiber] render boundary in fallback if it contains a new stylesheet during sync update (#28965)
Updates Suspensey instances and resources to preload even during urgent
updates and to potentially suspend.

The current implementation is unchanged for transitions but for sync
updates if there is a suspense boundary above the resource/instance it
will be rendered in fallback mode instead.

Note: This behavior is not what we want for images once we make them
suspense enabled. We will need to have forked behavior here to
distinguish between stylesheets which should never commit when not
loaded and images which should commit after a small delay
2024-05-21 16:03:46 -07:00
Dmytro Rykun
2c022b847e Clean up the enableEarlyReturnForPropDiffing experiment (#29041)
## Summary

The experiment has shown no significant performance changes. This PR
removes it.

## How did you test this change?
```
yarn flow native
yarn lint
```
2024-05-10 11:00:03 +01:00
Dmytro Rykun
b37e4b4e61 Clean up fastAddProperties and make it more correct (#29015)
## Summary

This PR makes some fixes to the `fastAddProperties` function:
- Use `if (!attributeConfig)` instead of `if (attributeConfig ===
undefined)` to account for `null`.
- If a prop has an Object `attributeConfig` with a `diff` function
defined on it, treat it as an atomic value to keep the semantics of
`diffProperties`.

## How did you test this change?

Build and run RNTester app.
2024-05-08 13:10:04 +01:00
Dmytro Rykun
7039834262 Create Fabric-specific version of ReactNativeAttributesPayload (#28841)
## Summary

This PR introduces Fabric-only version of
`ReactNativeAttributesPayload`. It is a copy-paste of
`ReactNativeAttributesPayload.js`, and is called
`ReactNativeAttributesPayloadFabric.js`.
The idea behind this change is that certain optimizations in prop
diffing may actually be a regression on the old architecture. For
example, removing custom diffing may result in larger updateProps
payloads. Which is, I guess, fine with JSI, but might be a problem with
the bridge.

## How did you test this change?

There should be no runtime effect of this change.
2024-05-07 11:53:36 +01:00
Dmytro Rykun
73bcdfbae5 Introduce a faster version of the addProperties function (#28969)
## Summary

This PR introduces a faster version of the `addProperties` function.
This new function is basically the `diffProperties` with `prevProps` set
to `null`, propagated constants, and all the unreachable code paths
collapsed.

## How did you test this change?

I've tested this change with [the benchmark
app](https://github.com/react-native-community/RNNewArchitectureApp/tree/new-architecture-benchmarks)
and got ~4.4% improvement in the view creation time.
2024-05-02 17:10:13 +01:00
Pieter De Baets
d779eba4b3 [react-native] Add unit test to ReactNativeAttributePayload (#28955)
## Summary

I'm looking at cleaning up some unnecessary manual property flattening
in React Native and wanted to verify this behaviour is working as
expected, where properties from nested objects will always overwrite
properties from the base object.

## How did you test this change?

Unit tests
2024-04-29 19:57:32 -07:00
Josh Story
94eed63c49 (Land #28798) Move Current Owner (and Cache) to an Async Dispatcher (#28912)
Rebasing and landing https://github.com/facebook/react/pull/28798

This PR was approved already but held back to give time for the sync.
Rebased and landing here without pushing to seb's remote to avoid
possibility of lost updates

---------

Co-authored-by: Sebastian Markbage <sebastian@calyptus.eu>
2024-04-25 10:40:40 -07:00
Sebastian Silbermann
82d8129e58 Reconciler: Change commitUpdate signature to account for unused updatePayload parameter (#28909) 2024-04-25 19:14:06 +02:00
Dmytro Rykun
0061ca6cf4 Add early return to diffProperties (#28842)
## Summary

This PR adds early return to the `diff` function. We don't need to go
through all the entries of `nextProps`, process and deep-diff the values
if `nextProps` is the same object as `prevProps`. Roughly 6% of all
`diffProperties` calls can be skipped.

## How did you test this change?

RNTester.
2024-04-18 17:24:07 +01:00
Ricky
b5e5ce8e0a Update ReactNativeTypes for root options (part 2) (#28857)
Forgot to push a change before mergin
https://github.com/facebook/react/pull/28850
2024-04-17 14:56:43 -04:00
Ricky
657428a9e9 Add ReactNativeTypes for root options (#28850)
Flow should have failed for this but didn't, we need these options
sync'd over in the types too.
2024-04-16 21:18:16 -04:00
Ricky
0347fcd007 Add on(Caught|Uncaught|Recoverable) opts to RN (#28836)
## Overview

There's currently a bug in RN now that we no longer re-throw errors. The
`showErrorDialog` function in React Native only logs the errors as soft
errors, and never a fatal. RN was depending on the global handler for
the fatal error handling and logging.

Instead of fixing this in `ReactFiberErrorDialog`, we can implement the
new root options in RN to handle caught/uncaught/recoverable in the
respective functions, and delete ReactFiberErrorDialog. I'll follow up
with a RN PR to implement these options and fix the error handling.
2024-04-15 12:03:28 -04:00
Andrew Clark
41950d14a5 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.
2024-04-10 16:54:24 -04:00
Sebastian Markbåge
d50323eb84 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.
2024-04-08 19:23:23 -04:00
Josh Story
8e1462e8c4 [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
2024-04-08 08:53:17 -07:00
Sebastian Markbåge
f33a6b69c6 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.
2024-04-05 12:48:52 -04:00
Sebastian Markbåge
5de8703646 Use the disableLegacyMode where ever we check the ConcurrentMode mode (#28657)
Saves some bytes and ensures that we're actually disabling it.

Turns out this flag wasn't disabling React Native/Fabric, React Noop and
React ART legacy modes so those are updated too.

Should be rebased on #28681.
2024-04-02 21:07:28 -04:00
Sebastian Markbåge
a053716077 Make onUncaughtError and onCaughtError Configurable (#28641)
Stacked on #28627.

This makes error logging configurable using these
`createRoot`/`hydrateRoot` options:

```
onUncaughtError(error: mixed, errorInfo: {componentStack?: ?string}) => void
onCaughtError(error: mixed, errorInfo: {componentStack?: ?string, errorBoundary?: ?React.Component<any, any>}) => void
onRecoverableError(error: mixed, errorInfo: {digest?: ?string, componentStack?: ?string}) => void
```

We already have the `onRecoverableError` option since before.

Overriding these can be used to implement custom error dialogs (with
access to the `componentStack`).

It can also be used to silence caught errors when testing an error
boundary or if you prefer not getting logs for caught errors that you've
already handled in an error boundary.

I currently expose the error boundary instance but I think we should
probably remove that since it doesn't make sense for non-class error
boundaries and isn't very useful anyway. It's also unclear what it
should do when an error is rethrown from one boundary to another.

Since these are public APIs now we can implement the
ReactFiberErrorDialog forks using these options at the roots of the
builds. So I unforked those files and instead passed a custom option for
the native and www builds.

To do this I had to fork the ReactDOMLegacy file into ReactDOMRootFB
which is a duplication but that will go away as soon as the FB fork is
the only legacy root.
2024-03-27 00:51:37 -04:00
Sebastian Markbåge
6786563f3c [Fiber] Don't Rethrow Errors at the Root (#28627)
Stacked on top of #28498 for test fixes.

### Don't Rethrow

When we started React it was 1:1 setState calls a series of renders and
if they error, it errors where the setState was called. Simple. However,
then batching came and the error actually got thrown somewhere else.
With concurrent mode, it's not even possible to get setState itself to
throw anymore.

In fact, all APIs that can rethrow out of React are executed either at
the root of the scheduler or inside a DOM event handler.
If you throw inside a React.startTransition callback that's sync, then
that will bubble out of the startTransition but if you throw inside an
async callback or a useTransition we now need to handle it at the hook
site. So in 19 we need to make all React.startTransition swallow the
error (and report them to reportError).

The only one remaining that can throw is flushSync but it doesn't really
make sense for it to throw at the callsite neither because batching.
Just because something rendered in this flush doesn't mean it was
rendered due to what was just scheduled and doesn't mean that it should
abort any of the remaining code afterwards. setState is fire and forget.
It's send an instruction elsewhere, it's not part of the current
imperative code.

Error boundaries never rethrow. Since you should really always have
error boundaries, most of the time, it wouldn't rethrow anyway.

Rethrowing also actually currently drops errors on the floor since we
can only rethrow the first error, so to avoid that we'd need to call
reportError anyway. This happens in RN events.

The other issue with rethrowing is that it logs an extra console.error.
Since we're not sure that user code will actually log it anywhere we
still log it too just like we do with errors inside error boundaries
which leads all of these to log twice.
The goal of this PR is to never rethrow out of React instead, errors
outside of error boundaries get logged to reportError. Event system
errors too.

### Breaking Changes

The main thing this affects is testing where you want to inspect the
errors thrown. To make it easier to port, if you're inside `act` we
track the error into act in an aggregate error and then rethrow it at
the root of `act`. Unlike before though, if you flush synchronously
inside of act it'll still continue until the end of act before
rethrowing.

I expect most user code breakages would be to migrate from `flushSync`
to `act` if you assert on throwing.

However, in the React repo we also have `internalAct` and the
`waitForThrow` helpers. Since these have to use public production
implementations we track these using the global onerror or process
uncaughtException. Unlike regular act, includes both event handler
errors and onRecoverableError by default too. Not just render/commit
errors. So I had to account for that in our tests.

We restore logging an extra log for uncaught errors after the main log
with the component stack in it. We use `console.warn`. This is not yet
ignorable if you preventDefault to the main error event. To avoid
confusion if you don't end up logging the error to console I just added
`An error occurred`.

### Polyfill

All browsers we support really supports `reportError` but not all test
and server environments do, so I implemented a polyfill for browser and
node in `shared/reportGlobalError`. I don't love that this is included
in all builds and gets duplicated into isomorphic even though it's not
actually needed in production. Maybe in the future we can require a
polyfill for this.

### Follow Ups

In a follow up, I'll make caught vs uncaught error handling be
configurable too.

---------

Co-authored-by: Ricky Hanlon <rickhanlonii@gmail.com>
2024-03-26 23:44:07 -04:00
Jan Kassens
6708115937 Use declare const instead of declare var (#28599)
Use `declare const` instead of `declare var`
2024-03-22 11:20:18 -04:00
Rubén Norte
bb0944fe5b [RN] Use microtasks in the RN renderer based on a global flag defined by RN (#28472)
## Summary

We want to enable the new event loop in React Native
(https://github.com/react-native-community/discussions-and-proposals/pull/744)
for all users in the new architecture (determined by the use of
bridgeless, not by the use of Fabric). In order to leverage that, we
need to also set the flag for the React reconciler to use microtasks for
scheduling (so we'll execute them at the right time in the new event
loop).

This migrates from the previous approach using a dynamic flag (to be
used at Meta) with the check of a global set by React Native. The reason
for doing this is:
1) We still need to determine this dynamically in OSS (based on
Bridgeless, not on Fabric).
2) We still need the ability to configure the behavior at Meta, and for
internal build system reasons we cannot access the flag that enables
microtasks in
[`ReactNativeFeatureFlags`](6c28c87c4d/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js (L121)).

## How did you test this change?

Manually synchronized the changes to React Native and ran all tests for
the new architecture on it. Also tested manually.

> [!NOTE]
> This change depends on
https://github.com/facebook/react-native/pull/43397 which has been
merged already
2024-03-13 10:00:10 +00:00
Sebastian Markbåge
89021fb4ec Remove invokeGuardedCallback and replay trick (#28515)
We broke the ability to "break on uncaught exceptions" by adding a
try/catch higher up in the scheduling. We're giving up on fixing that so
we can remove the replay trick inside an event handler.

The issue with that approach is that we end up double logging a lot of
errors in DEV since they get reported to the page.

It's also a lot of complexity around this feature.
2024-03-11 20:17:07 -04:00
Ricky
1940cb27b2 Update /link URLs to react.dev (#28477)
Depends on https://github.com/reactjs/react.dev/pull/6670 [merged]
2024-03-03 17:34:33 -05:00
Sebastian Markbåge
d579e77482 Remove method name prefix from warnings and errors (#28432)
This pattern is a petpeeve of mine. I don't consider this best practice
and so most don't have these prefixes. Very inconsistent.

At best this is useless and noisey that you have to parse because the
information is also in the stack trace.

At worse these are misleading because they're highlighting something
internal (like validateDOMNesting) which even suggests an internal bug.
Even the ones public to React aren't necessarily what you called because
you might be calling a wrapper around it.

That would be properly reflected in a stack trace - which can also
properly ignore list so that the first stack you see is your callsite,

Which might be like `render()` in react-testing-library rather than
`createRoot()` for example.
2024-02-23 15:16:54 -05:00
Sebastian Markbåge
37d901e2b8 Remove __self and __source location from elements (#28265)
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.
2024-02-07 16:38:00 -05:00
Sebastian Silbermann
2a45118b10 Convert ResponderEventPlugin to createRoot (#28190) 2024-02-01 18:53:25 -05:00
Ruslan Lesiutin
6639ed3b3a refactor[isChildPublicInstance]: don't leak ReactNativeFiberHostComponent to Fabric implementation (#27923)
While inspecting the build artifacts for Fabric in
https://www.internalfb.com/diff/D51816108, I've noticed it has some
leaking implementation details from Paper, such as
`ReactNativeFiberHostComponent`.

The reason for it is the single implementation of
`isChildPublicInstance` in `ReactNativePublicCompat`, in which we were
using `instanceof ReactNativeFiberHostComponent`.

This new implementation removes the `ReactNativeFiberHostComponent`
leak, but decreases the Flow coverage.
2024-01-11 14:26:39 +00:00
Ruslan Lesiutin
c29ca23af9 fix: add isChildPublicInstance to ReactNativeTypes (#27788)
Follow-up on https://github.com/facebook/react/pull/27783.

React Native is actually using `ReactNativeTypes`, which are synced from
this repo. In order to make `isChildPublicInstance` visible for
renderers inside React Native repository, we need to list it in
`ReactNativeTypes`.

Because of current circular dependency between React Native and React,
it is impossible to actually type it properly:
- Can't import any types in `ReactNativeTypes` from local files, because
it will break React Native, once synced.
- Implementations can't use real types in their definitions, because it
will break these checks:


223db40d5a/packages/react-native-renderer/fabric.js (L12-L13)


223db40d5a/packages/react-native-renderer/index.js (L12-L14)
2023-12-05 13:00:59 +00:00
Ruslan Lesiutin
1729b499ed feat[Fabric/Paper]: support isChildPublicInstance api method (#27783)
Adds `isChildPublicInstance` method to both renderers (Fabric and
Paper), which will receive 2 public instances and return if first
argument is an ancestor of the second, based on fibers.

This will be used as a fallback when DOM node APIs are not available:
for Paper renderer or for Fabric without DOM node APIs.

How it is going to be used: to determine which `AppContainer` component
in RN is responsible for highlighting an inspected element on the
screen.
2023-12-04 17:22:03 +00:00
Jan Kassens
432b9f1d97 Upgrade Flow to 0.221.0 (#27689)
Upgrades Flow and dependencies
```
yarn add -W flow-bin flow-remove-types hermes-parser hermes-eslint
```
2023-11-10 14:14:53 -05:00
Rubén Norte
6b3834a45b Guard against unmounted components when accessing public instances on Fabric (#27687)
## Summary

This fixes an error in `getPublicInstanceFromInstanceHandle` where we
throw an error when trying to access the public instance from the fiber
of an unmounted component. This shouldn't throw but return `null`
instead.

## How did you test this change?

Updated unit tests.
Before: 
<img width="969" alt="Screenshot 2023-11-10 at 15 26 14"
src="https://github.com/facebook/react/assets/117921/ea161616-2775-4fab-8d74-da4bef48d09a">

After: 
<img width="1148" alt="Screenshot 2023-11-10 at 15 28 37"
src="https://github.com/facebook/react/assets/117921/db18b918-b6b6-4925-9cfc-3b4b2f3ab92d">
2023-11-10 15:49:07 +00:00
Andrew Clark
77c4ac2ce8 [useFormState] Allow sync actions (#27571)
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.
2023-10-31 23:32:31 -04:00
Jakub Romańczyk
ea8a8619ce refactor: use ESM exports in ReactNativeViewConfigRegistry (#27508)
## Summary

When transpiling `react-native` with `swc` this file caused some trouble
as it mixes ESM and CJS import/export syntax. This PR addresses this by
converting CJS exports to ESM exports. As
`ReactNativeViewConfigRegistry` is synced from `react` to `react-native`
repository, it's required to make the change here. I've also aligned the
mock of `ReactNativeViewConfigRegistry` to reflect current
implementation.

Related PR in `react-native`:
https://github.com/facebook/react-native/pull/40787
2023-10-12 17:28:32 +01:00
Pieter De Baets
151e75a128 [Fabric] Pass children when cloning (#27458)
## 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.
2023-10-10 15:11:26 +01:00
Rubén Norte
54baa7997c Add feature flag to use microtasks in the React Native Fabric renderer (#27364)
## Summary

This is part of an effort to align the event loop in React Native with
its behavior on the Web. In this case, we're going to test enabling
microtasks in React Native (Fabric) and we need React to schedule work
using microtasks if available there. This just adds a feature flag to
configure that behavior at runtime.

## How did you test this change?

* Reviewed the generated code, which looks ok.
* Did a manual sync of this PR to Meta's internal infra and tested it
with my changes to enable microtasks in RN/Hermes.
2023-10-02 17:12:35 +01:00