Commit Graph
926 Commits
Author SHA1 Message Date
Jack PopeandGitHub 6aa8254bb7 Add ref to Fragment (#32465)
*This API is experimental and subject to change or removal.*

This PR is an alternative to
https://github.com/facebook/react/pull/32421 based on feedback:
https://github.com/facebook/react/pull/32421#pullrequestreview-2625382015
. The difference here is that we traverse from the Fragment's fiber at
operation time instead of keeping a set of children on the
`FragmentInstance`. We still need to handle newly added or removed child
nodes to apply event listeners and observers, so we treat those updates
as effects.

**Fragment Refs**

This PR extends React's Fragment component to accept a `ref` prop. The
Fragment's ref will attach to a custom host instance, which will provide
an Element-like API for working with the Fragment's host parent and host
children.

Here I've implemented `addEventListener`, `removeEventListener`, and
`focus` to get started but we'll be iterating on this by adding
additional APIs in future PRs. This sets up the mechanism to attach refs
and perform operations on children. The FragmentInstance is implemented
in `react-dom` here but is planned for Fabric as well.

The API works by targeting the first level of host children and proxying
Element-like APIs to allow developers to manage groups of elements or
elements that cannot be easily accessed such as from a third-party
library or deep in a tree of Functional Component wrappers.

```javascript
import {Fragment, useRef} from 'react';

const fragmentRef = useRef(null);

<Fragment ref={fragmentRef}>
  <div id="A" />
  <Wrapper>
    <div id="B">
      <div id="C" />
    </div>
  </Wrapper>
  <div id="D" />
</Fragment>
```

In this case, calling `fragmentRef.current.addEventListener()` would
apply an event listener to `A`, `B`, and `D`. `C` is skipped because it
is nested under the first level of Host Component. If another Host
Component was appended as a sibling to `A`, `B`, or `D`, the event
listener would be applied to that element as well and any other APIs
would also affect the newly added child.

This is an implementation of the basic feature as a starting point for
feedback and further iteration.
2025-03-12 10:32:11 -04:00
RickyandGitHub e0fe347967 [flags] remove enableOwnerStacks (#32426)
Bassed off: https://github.com/facebook/react/pull/32425

Wait to land internally.

[Commit to
review.](https://github.com/facebook/react/pull/32426/commits/66aa6a4dbb78106b4f3d3eb367f5c27eb8f30c66)

This has landed everywhere
2025-03-04 12:34:34 -05:00
Sam ZhouandGitHub 70f1d766e8 [flow] Eliminate usage of global React types in ReactNativeTypes.js (#32330) 2025-02-20 12:42:33 -05:00
michael faithandGitHub 0d9834caeb build: add support to the rollup build for building typescript packages (#32393) 2025-02-16 10:38:13 -05:00
Sebastian MarkbågeandGitHub a53da6abe1 Add useSwipeTransition Hook Behind Experimental Flag (#32373)
This Hook will be used to drive a View Transition based on a gesture.

```js
const [value, startGesture] = useSwipeTransition(prev, current, next);
```

The `enableSwipeTransition` flag will depend on `enableViewTransition`
flag but we may decide to ship them independently. This PR doesn't do
anything interesting yet. There will be a lot more PRs to build out the
actual functionality. This is just wiring up the plumbing for the new
Hook.

This first PR is mainly concerned with how the whole starts (and stops).
The core API is the `startGesture` function (although there will be
other conveniences added in the future). You can call this to start a
gesture with a source provider. You can call this multiple times in one
event to batch multiple Hooks listening to the same provider. However,
each render can only handle one source provider at a time and so it does
one render per scheduled gesture provider.

This uses a separate `GestureLane` to drive gesture renders by marking
the Hook as having an update on that lane. Then schedule a render. These
renders should be blocking and in the same microtask as the
`startGesture` to ensure it can block the paint. So it's similar to
sync.

It may not be possible to finish it synchronously e.g. if something
suspends. If so, it just tries again later when it can like any other
render. This can also happen because it also may not be possible to
drive more than one gesture at a time like if we're limited to one View
Transition per document. So right now you can only run one gesture at a
time in practice.

These renders never commit. This means that we can't clear the
`GestureLane` the normal way. Instead, we have to clear only the root's
`pendingLanes` if we don't have any new renders scheduled. Then wait
until something else updates the Fiber after all gestures on it have
stopped before it really clears.
2025-02-13 16:06:01 -05:00
Sebastian "Sebbie" SilbermannandGitHub 32b0cad8f7 Enable owner stacks in Canary builds (#32053)
Pending internal decision to ship in Canary.
Still off for FB builds.

Docs: https://github.com/reactjs/react.dev/pull/7427
2025-02-13 14:38:57 -05:00
Sebastian "Sebbie" SilbermannandGitHub ed8b68dd17 Stop exporting dev-only methods in OSS production builds (#32200) 2025-02-13 18:26:36 +01:00
192555bb0e Added dev-only warning for null/undefined create in use*Effect (#32355)
## Summary

Fixes #32354.

Re-creation of #15197: adds a dev-only warning if `create == null` to
the three `use*Effect` functions:

* `useEffect`
* `useInsertionEffect`
* `useLayoutEffect`

Updates the warning to match the same text given in the
`react/exhaustive-deps` lint rule.

## How did you test this change?

I applied the changes manually within `node_modules/` on a local clone
of
https://github.com/JoshuaKGoldberg/repros/tree/react-use-effect-no-arguments.

Please pardon me for opening a PR addressing a not-accepted issue. I was
excited to get back to #15194 -> #15197 now that I have time. 🙂

---------

Co-authored-by: lauren <poteto@users.noreply.github.com>
2025-02-11 17:01:04 -05:00
laurenandGitHub a69b80d07e [crud] Remove useResourceEffect (#32206)
Removes useResourceEffect.
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32206).
* __->__ #32206
* #32205
2025-02-11 14:19:34 -05:00
laurenandGitHub 2c5fd26c07 [crud] Merge useResourceEffect into useEffect (#32205)
Merges the useResourceEffect API into useEffect while keeping the
underlying implementation the same. useResourceEffect will be removed in
the next diff.

To fork between behavior we rely on a `typeof` check for the updater or
destroy function in addition to the CRUD feature flag. This does now
have to be checked every time (instead of inlined statically like before
due to them being different hooks) which will incur some non-zero amount
(possibly negligble) of overhead for every effect.
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32205).
* #32206
* __->__ #32205
2025-02-11 14:18:50 -05:00
laurenandGitHub 0461c0d8a4 [crud] Rename useResourceEffect flag (#32204)
Rename the flag in preparation for the overload.
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32204).
* #32206
* #32205
* __->__ #32204
2025-02-11 14:05:50 -05:00
laurenandGitHub 899e3d1297 [crud] Narrow resource type (#32203)
Small refactor to the `resource` type to narrow it to an arbitrary
object or void/null instead of the top type. This makes the overload on
useEffect simpler since the return type of create is no longer widened
to the top type when we merge their definitions.
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32203).
* #32206
* #32205
* #32204
* __->__ #32203
2025-02-11 13:52:25 -05:00
Sebastian MarkbågeandGitHub 594ea533d3 Remove useActionState Hook export from experimental react-server condition (#32342)
This Hook is not available in RSC environments. This is already the case
in stable but not in experimental for some reason. Probably an
oversight.
2025-02-09 15:01:28 -05:00
RickyandGitHub ff6283340a Export addTransitionType for www (#32311)
need dis based api
2025-02-05 18:31:32 -05:00
Jack PopeandGitHub 32b411496b Set enableViewTransition to dynamic for www (#32306)
Unblocks internal experimentation
2025-02-04 15:53:03 -05:00
Timothy YungandGitHub 9ff42a8798 Permit non-DEV Elements in React.Children w/ DEV (#32117) 2025-01-30 22:59:45 -08:00
Sebastian MarkbågeandGitHub 028c8e6cf5 Add Transition Types (#32105)
This adds an isomorphic API to add Transition Types, which represent the
cause, to the current Transition. This is currently mainly for View
Transitions but as a concept it's broader and we might expand it to more
features and object types in the future.

```js
import { unstable_addTransitionType as addTransitionType } from 'react';

startTransition(() => {
  addTransitionType('my-transition-type');
  setState(...);
});
```

If multiple transitions get entangled this is additive and all
Transition Types are collected. You can also add more than one type to a
Transition (hence the `add` prefix).

Transition Types are reset after each commit. Meaning that `<Suspense>`
revealing after a `startTransition` does not get any View Transition
types associated with it.

Note that the scoping rules for this is a little "wrong" in this
implementation. Ideally it would be scoped to the nearest outer
`startTransition` and grouped with any `setState` inside of it.
Including Actions. However, since we currently don't have AsyncContext
on the client, it would be too easy to drop a Transition Type if there
were no other `setState` in the same `await` task. Multiple Transitions
are entangled together anyway right now as a result. So this just tracks
a global of all pending Transition Types for the next Transition. An
inherent tricky bit with this API is that you could update multiple
roots. In that case it should ideally be associated with each root.
Transition Tracing solves this by associating a Transition with any
updates that are later collected but this suffers from the problem
mentioned above. Therefore, I just associate Transition Types with one
root - the first one to commit. Since the View Transitions across roots
are sequential anyway it kind of makes sense that only one really is the
cause and the other one is subsequent.

Transition Types can be used to apply different animations based on what
caused the Transition. You have three different ways to choose from for
how to use them:

## CSS

It integrates with [View Transition
Types](https://www.w3.org/TR/css-view-transitions-2/#active-view-transition-pseudo-examples)
so you can match different animations based on CSS scopes:

```css
:root:active-view-transition-type(my-transition-type) {
  &::view-transition-...(...) {
    ...
  }
}
```

This is kind of a PITA to write though and if you have a CSS library
that provide View Transition Classes it's difficult to import those into
these scopes.

## Class per Type

This PR also adds an object-as-map form that can be passed to all
`className` properties:

```js
<ViewTransition className={{
  'my-navigation-type': 'hello',
  'default': 'world',
}}>
```

If multiple types match, then they're joined together. If no types match
then the special `"default"` entry is used instead. If any type has the
value `"none"` then that wins and the ViewTransition is disabled (not
assigned a name).

These can be combined with `enter`/`exit`/`update`/`layout`/`share`
props to match based on kind of trigger and Transition Type.

```js
<ViewTransition enter={{
  'navigation-back': 'enter-right',
  'navigation-forward': 'enter-left',
}}
exit={{
  'navigation-back': 'exit-right',
  'navigation-forward': 'exit-left',
}}>
```

## Events

In addition, you can also observe the types in the View Transition Event
callbacks as the second argument. That way you can pick different
imperative Animations based on the cause.

```js
<ViewTransition onUpdate={(inst, types) => {
  if (types.includes('navigation-back')) {
    ...
  } else if (types.includes('navigation-forward')) {
    ...
  } else {
    ...
  }
}}>
```

## Future

In the future we might expose types to `useEffect` for more general
purpose usage. This would also allow non-View Transition based
Animations such as existing libraries to use this same feature to
coordinate the same concept.

We might also allow richer objects to be passed along here. Only the
strings would apply to View Transitions but the imperative code and
effects could do something else with them.
2025-01-21 15:00:02 -05:00
Sebastian "Sebbie" SilbermannandGitHub 6099351c76 Use internal ReactCompilerRuntime in react/compiler-runtime entrypoint (#32054) 2025-01-13 19:42:20 +01:00
a4d122f2d1 Add <ViewTransition> Component (#31975)
This will provide the opt-in for using [View
Transitions](https://developer.mozilla.org/en-US/docs/Web/API/View_Transition_API)
in React.

View Transitions only trigger for async updates like `startTransition`,
`useDeferredValue`, Actions or `<Suspense>` revealing from fallback to
content. Synchronous updates provide an opt-out but also guarantee that
they commit immediately which View Transitions can't.

There's no need to opt-in to View Transitions at the "cause" side like
event handlers or actions. They don't know what UI will change and
whether that has an animated transition described.

Conceptually the `<ViewTransition>` component is like a DOM fragment
that transitions its children in its own isolate/snapshot. The API works
by wrapping a DOM node or inner component:

```js
import {ViewTransition} from 'react';

<ViewTransition><Component /></ViewTransition>
```

The default is `name="auto"` which will automatically assign a
`view-transition-name` to the inner DOM node. That way you can add a
View Transition to a Component without controlling its DOM nodes styling
otherwise.

A difference between this and the browser's built-in
`view-transition-name: auto` is that switching the DOM nodes within the
`<ViewTransition>` component preserves the same name so this example
cross-fades between the DOM nodes instead of causing an exit and enter:

```js
<ViewTransition>{condition ? <ComponentA /> : <ComponentB />}</ViewTransition>
```

This becomes especially useful with `<Suspense>` as this example
cross-fades between Skeleton and Content:

```js
<ViewTransition>
  <Suspense fallback={<Skeleton />}>
    <Content />
  </Suspense>
</ViewTransition>
```

Where as this example triggers an exit of the Skeleton and an enter of
the Content:

```js
<Suspense fallback={<ViewTransition><Skeleton /></ViewTransition>}>
  <ViewTransition><Content /></ViewTransition>
</Suspense>
```

Managing instances and keys becomes extra important.

You can also specify an explicit `name` property for example for
animating the same conceptual item from one page onto another. However,
best practices is to property namespace these since they can easily
collide. It's also useful to add an `id` to it if available.

```js
<ViewTransition name="my-shared-view">
```

The model in general is the same as plain `view-transition-name` except
React manages a set of heuristics for when to apply it. A problem with
the naive View Transitions model is that it overly opts in every
boundary that *might* transition into transitioning. This is leads to
unfortunate effects like things floating around when unrelated updates
happen. This leads the whole document to animate which means that
nothing is clickable in the meantime. It makes it not useful for smaller
and more local transitions. Best practice is to add
`view-transition-name` only right before you're about to need to animate
the thing. This is tricky to manage globally on complex apps and is not
compositional. Instead we let React manage when a `<ViewTransition>`
"activates" and add/remove the `view-transition-name`. This is also when
React calls `startViewTransition` behind the scenes while it mutates the
DOM.

I've come up with a number of heuristics that I think will make a lot
easier to coordinate this. The principle is that only if something that
updates that particular boundary do we activate it. I hope that one day
maybe browsers will have something like these built-in and we can remove
our implementation.

A `<ViewTransition>` only activates if:

- If a mounted Component renders a `<ViewTransition>` within it outside
the first DOM node, and it is within the viewport, then that
ViewTransition activates as an "enter" animation. This avoids inner
"enter" animations trigger when the parent mounts.
- If an unmounted Component had a `<ViewTransition>` within it outside
the first DOM node, and it was within the viewport, then that
ViewTransition activates as an "exit" animation. This avoids inner
"exit" animations triggering when the parent unmounts.
- If an explicitly named `<ViewTransition name="...">` is deep within an
unmounted tree and one with the same name appears in a mounted tree at
the same time, then both are activated as a pair, but only if they're
both in the viewport. This avoids these triggering "enter" or "exit"
animations when going between parents that don't have a pair.
- If an already mounted `<ViewTransition>` is visible and a DOM
mutation, that might affect how it's painted, happens within its
children but outside any nested `<ViewTransition>`. This allows it to
"cross-fade" between its updates.
- If an already mounted `<ViewTransition>` resizes or moves as the
result of direct DOM nodes siblings changing or moving around. This
allows insertion, deletion and reorders into a list to animate all
children. It is only within one DOM node though, to avoid unrelated
changes in the parent to trigger this. If an item is outside the
viewport before and after, then it's skipped to avoid things flying
across the screen.
- If a `<ViewTransition>` boundary changes size, due to a DOM mutation
within it, then the parent activates (or the root document if there are
no more parents). This ensures that the container can cross-fade to
avoid abrupt relayout. This can be avoided by using absolutely
positioned children. When this can avoid bubbling to the root document,
whatever is not animating is still responsive to clicks during the
transition.

Conceptually each DOM node has its own default that activates the parent
`<ViewTransition>` or no transition if the parent is the root. That
means that if you add a DOM node like `<div><ViewTransition><Component
/></ViewTransition></div>` this won't trigger an "enter" animation since
it was the div that was added, not the ViewTransition. Instead, it might
cause a cross-fade of the parent ViewTransition or no transition if it
had no parent. This ensures that only explicit boundaries perform coarse
animations instead of every single node which is really the benefit of
the View Transitions model. This ends up working out well for simple
cases like switching between two pages immediately while transitioning
one floating item that appears on both pages. Because only the floating
item transitions by default.

Note that it's possible to add manual `view-transition-name` with CSS or
`style={{ viewTransitionName: 'auto' }}` that always transitions as long
as something else has a `<ViewTransition>` that activates. For example a
`<ViewTransition>` can wrap a whole page for a cross-fade but inside of
it an explicit name can be added to something to ensure it animates as a
move when something relates else changes its layout. Instead of just
cross-fading it along with the Page which would be the default.

There's more PRs coming with some optimizations, fixes and expanded
APIs. This first PR explores the above core heuristic.

---------

Co-authored-by: Sebastian "Sebbie" Silbermann <silbermann.sebastian@gmail.com>
2025-01-08 12:11:18 -05:00
RickyandGitHub 379089d288 [flags] remove enableDeferRootSchedulingToMicrotask (#32008)
Wait for me to merge, but this has landed everywhere and is ready to
remove.
2025-01-08 12:03:01 -05:00
RickyandGitHub 94867f33be [asserts helpers] react package (#31853)
Based off https://github.com/facebook/react/pull/31844

Commit to review:
https://github.com/facebook/react/commit/11aa104e3e70c0accc21f785060b812beb145089

Converts the rest of the `react` package.
2024-12-23 14:58:20 -05:00
RickyandGitHub 36d15d5862 [assert helpers] ReactChildren-test (#31844)
Based off https://github.com/facebook/react/pull/31843

Commit to review:
https://github.com/facebook/react/pull/31844/commits/2c653b81a73e155f1548c0362e5334629a45351e

Moar tests
2024-12-19 13:05:23 -05:00
RickyandGitHub 8f92ea467e [assert helpers] forwardRef-test (#31843)
Starting to convert the rest of tests to the `assertConsoleTypeDev`
helpers.
2024-12-19 11:50:05 -05:00
RickyandGitHub faf6c4dfdc [flags] Remove debugRenderPhaseSideEffectsForStrictMode (#31839)
This is enabled everywhere, we can just use the inline `__DEV__` checks.
2024-12-18 17:51:12 -05:00
RickyandGitHub e1d843f4d8 [tests] <StrictMode /> nested in tree is broken (#31825)
Adds a test that shows using <StrictMode /> anywhere outside of the root
node will not fire strict effects.

This works:

```js
root.render(
  <StrictMode>
    <App>
      <Children />
    </App>
  </StrictMode>
);
  ```
  
  This does not fire strict effects on mount:
```js
root.render(
  <App>
    <StrictMode>
      <Children />
    </StrictMode>
  </App>
);
```
2024-12-18 13:29:41 -05:00
2bd1c756c6 Ensure function arity is preserved after build (#31808)
Co-authored-by: eps1lon <sebastian.silbermann@vercel.com>
2024-12-18 14:08:56 +01:00
Jack PopeandGitHub 34ee3919c3 Clean up enableLazyContextPropagation (#31810)
This flag has shipped everywhere, let's clean it up.
2024-12-17 11:56:00 -05:00
Jack PopeandGitHub 909ed63e0a Clean up context access profiling experiment (#31806)
We introduced the `unstable_useContextWithBailout` API to run compiler
based experiments. This API was designed to be an experiment proxy for
alternative approaches which would be heavier to implement. The
experiment turned out to be inconclusive. Since most of our performance
critical usage is already optimized, we weren't able to find a clear win
with this approach.

Since we don't have further plans for this API, let's clean it up.
2024-12-16 12:32:07 -05:00
RickyandGitHub 2d320563f3 [flags] Delete enableDebugTracing (#31780)
This is unused, even in the one builds that uses it, and we don't plan
on landing it in this form.
2024-12-15 12:16:10 -05:00
RickyandGitHub 08dfd0b805 Remove enableBinaryflight (#31759)
Based off https://github.com/facebook/react/pull/31757

This has landed everywhere.
2024-12-13 14:50:13 -05:00
RickyandGitHub ef63718a27 Remove enableAsyncActions (#31757)
Based on https://github.com/facebook/react/pull/31756

This is landed everywhere
2024-12-13 13:58:18 -05:00
RickyandGitHub 4dff0e62b2 Remove consoleManagedByDevToolsDuringStrictMode (#31755)
This is enabled everywhere except the test renderers, which don't use
it.
2024-12-13 11:05:10 -05:00
c86542b240 Bump next prerelease version numbers (#31676)
Updates the version numbers in the prerelease (canary and experimental)
channels.

---------

Co-authored-by: Jack Pope <jackpope1@gmail.com>
2024-12-12 14:10:46 -05:00
a4964987dc Make enableOwnerStacks dynamic (#31661)
following up on https://github.com/facebook/react/pull/31287, fixing
tests

---------

Co-authored-by: Rick Hanlon <rickhanlonii@fb.com>
2024-12-11 12:00:25 -05:00
laurenandGitHub e3b7ef32be [crud] Only export uRC when flag is enabled (#31617)
It's tricky to do feature detection of uRC currently because it's always
present on the export. Let's conditionally export it instead.
2024-11-22 16:13:42 -05:00
laurenandGitHub 047d95e85f [crud] Basic implementation (#31523)
This PR introduces a new experimental hook `useResourceEffect`, which is
something that we're doing some very early initial tests on.

This may likely not pan out and will be removed or modified if so.
Please do not rely on it as it will break.
2024-11-18 10:16:37 -05:00
laurenandGitHub d8afd1c82e [crud] Scaffold initial types (#31555)
Scaffolds the initial `useResourceEffect` dispatcher type. This will
eventually be folded into `useEffect` et al as an overload.

---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/31555).
* #31523
* #31557
* #31556
* __->__ #31555
2024-11-15 17:49:31 -05:00
Sebastian MarkbågeandGitHub 3720870a97 Log Render Phases that Never Committed (#31548)
This includes:

- `Interrupted Render`: Interrupted Renders (setState or ping at higher
priority)
- `Prewarm`: Suspended Renders outside a Suspense boundary
(RootSuspendedWithDelay/RootSuspendedAtTheShell)
- `Errored Render`: Render that errored somewhere in the tree (Fatal or
Not) (which may or may not be retried and then complete)
- `Teared Render`: Due to useSyncExternalStore not matching (which will
do another sync attempt)

Suspended Commit:

<img width="893" alt="Screenshot 2024-11-14 at 11 47 40 PM"
src="https://github.com/user-attachments/assets/b25a6a8b-a5e9-4d66-b325-57aef4bf9dad">

Errored with a second recovery attempt that also errors:

<img width="976" alt="Screenshot 2024-11-15 at 12 09 06 AM"
src="https://github.com/user-attachments/assets/9ce52cbb-b587-4f1e-8b67-e51d9073ae5b">
2024-11-15 12:13:24 -05:00
laurenandGitHub 5d89471ca6 Export __COMPILER_RUNTIME in stable (#31540)
In order to make use of the compiler in stable releases (eg React 19 RC,
canary), we need to export the compiler runtime in the stable channel as
well.
2024-11-14 15:46:35 -05:00
laurenandGitHub b15135b9f5 [ez] Update useMemoCache return type (#31539)
Use `mixed` instead of `any`
2024-11-14 12:10:51 -05:00
Jan KassensandGitHub e1378902bb [string-refs] cleanup string ref code (#31443) 2024-11-06 14:00:10 -05:00
Jan KassensandGitHub d1f04722d6 [string-refs] remove enableLogStringRefsProd flag (#31414)
We no longer need this production logging.
2024-11-06 09:00:49 -05:00
Jan KassensandGitHub 3dc1e4820e Followup: remove dead test code from #30346 (#31415)
I missed that this was a constant false check when making the broader
cleanup changes in https://github.com/facebook/react/pull/30346
2024-11-06 08:58:36 -05:00
Jan KassensandGitHub 07aa494432 Remove enableRefAsProp feature flag (#30346)
The flag is fully rolled out.
2024-11-04 14:30:58 -05:00
Sam ZhouandGitHub 45804af18d [flow] Eliminate usage of more than 1-arg React.AbstractComponent in React codebase (#31314)
<!--
  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

In order to adopt react 19's ref-as-prop model, Flow needs to eliminate
all the places where they are treated differently.
`React.AbstractComponent` is the worst example of this, and we need to
eliminate it.

This PR eliminates them from the react repo, and only keeps the one that
has 1 argument of props.

## How did you test this change?

yarn flow
2024-10-21 16:17:41 -07:00
Jan KassensandGitHub 5636fad840 [string-refs] log string ref from prod (#31161)
If passed as a feature flag, this calls the configured function when a
string ref is used even from prod code to find the last usages.
2024-10-10 18:12:47 -04:00
laurenandGitHub b78a7f2f35 [rcr] Re-export useMemoCache in top level React namespace (#31139)
In order to support using the compiler on versions of React prior to 19,
we need the ability to statically import `c` (aka useMemoCache) or
fallback to a polyfill supplied by `react-compiler-runtime` (note: this
is a separate npm package, not to be confused with
`react/compiler-runtime`, which is currently a part of react).

To do this we first need to re-export `useMemoCache` under the top level
React namespace again, which is additive and thus non-breaking. Doing so
allows `react-compiler-runtime` to statically either re-export
`React.__COMPILER_RUNTIME.c` or supply a polyfill, without the need for
a dynamic import which is finicky to support due to returning a promise.

In later PRs I will remove `react/compiler-runtime` and update the
compiler to emit imports to `react-compiler-runtime` instead.
2024-10-07 16:25:04 -04:00
Sebastian MarkbågeandGitHub 4e9540e3c2 [Fiber] Log the Render/Commit phases and the gaps in between (#31016)
A slight behavior change here too is that I now mark the start of the
commit phase before the BeforeMutationEffect phase. This affects
`<Profiler>` too.

The named sequences are as follows:

Render -> Suspended or Throttled -> Commit -> Waiting for Paint ->
Remaining Effects

The Suspended phase is only logged if we delay the Commit due to CSS /
images.

The Throttled phase is only logged if we delay the commit due to the
Suspense throttling timer.

<img width="1246" alt="Screenshot 2024-09-20 at 9 14 23 PM"
src="https://github.com/user-attachments/assets/8d01f444-bb85-472b-9b42-6157d92c81b4">

I don't yet log render phases that don't complete. I think I also need
to special case renders that or don't commit after being suspended.
2024-09-23 14:09:48 -04:00
Sebastian MarkbågeandGitHub d4688dfaaf [Fiber] Track Event Time, startTransition Time and setState Time (#31008)
This tracks the current window.event.timeStamp the first time we
setState or call startTransition. For either the blocking track or
transition track. We can use this to show how long we were blocked by
other events or overhead from when the user interacted until we got
called into React.

Then we track the time we start awaiting a Promise returned from
startTransition. We can use this track how long we waited on an Action
to complete before setState was called.

Then finally we track when setState was called so we can track how long
we were blocked by other word before we could actually start rendering.
For a Transition this might be blocked by Blocking React render work.

We only log these once a subsequent render actually happened. If no
render was actually scheduled, then we don't log these. E.g. if an
isomorphic Action doesn't call startTransition there's no render so we
don't log it.

We only log the first event/update/transition even if multiple are
batched into it later. If multiple Actions are entangled they're all
treated as one until an update happens. If no update happens and all
entangled actions finish, we clear the transition so that the next time
a new sequence starts we can log it.

We also clamp these (start the track later) if they were scheduled
within a render/commit. Since we share a single track we don't want to
create overlapping tracks.

The purpose of this is not to show every event/action that happens but
to show a prelude to how long we were blocked before a render started.
So you can follow the first event to commit.

<img width="674" alt="Screenshot 2024-09-20 at 1 59 58 AM"
src="https://github.com/user-attachments/assets/151ba9e8-6b3c-4fa1-9f8d-e3602745eeb7">

I still need to add the rendering/suspended phases to the timeline which
why this screenshot has a gap.

<img width="993" alt="Screenshot 2024-09-20 at 12 50 27 AM"
src="https://github.com/user-attachments/assets/155b6675-b78a-4a22-a32b-212c15051074">

In this case it's a Form Action which started a render into the form
which then suspended on the action. The action then caused a refresh,
which interrupts with its own update that's blocked before rendering.
Suspended roots like this is interesting because we could in theory
start working on a different root in the meantime which makes this
timeline less linear.
2024-09-20 14:27:12 -04:00
Sebastian MarkbågeandGitHub 15da917451 Don't read currentTransition back from internals (#30991)
This code is weird. It reads back the transition that it just set from
the shared internals. It's almost like it expects it to be a getter or
something.

This avoids that and makes it consistent with what ReactFiberHooks
already does.
2024-09-17 15:25:00 -04:00