Commit Graph

16609 Commits

Author SHA1 Message Date
Sebastian Markbåge fd0da3eef1 Remove _owner field from JSX elements in prod if string refs are disabled (#28739)
In prod, the `_owner` field is only used for string refs so if we have
string refs disabled, we don't need this field. In fact, that's one of
the big benefits of deprecating them.
2024-04-04 11:20:15 -04:00
Andrew Clark 48b4ecc901 Remove defaultProps support (except for classes) (#28733)
This removes defaultProps support for all component types except for
classes. We've chosen to continue supporting defaultProps for classes
because lots of older code relies on it, and unlike function components,
(which can use default params), there's no straightforward alternative.

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

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

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

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

In other words, previously `<ClassWithDefaultProp />.props.aDefaultProp`
would resolve to the default prop value, but now it does not.
2024-04-04 10:59:19 -04:00
Jack Pope 7966ccddc8 Enable stale action (#28729)
Follows #28695

Now that the action has run successfully in debug mode
([logs](https://github.com/facebook/react/actions/runs/8532177618/job/23372921455#step:2:35)),
let's enable it to persist changes.

Also changes the number of operations per run from the default of 30 to
100 since we have a large backlog of issues and PRs to work through.

Finally adds enhancement label as exempt from stale.
2024-04-04 10:27:29 -04:00
Sebastian Markbåge 6090cab099 Use a Wrapper Error for onRecoverableError with a "cause" Field for the real Error (#28736)
We basically have four kinds of recoverable errors:

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

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

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

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

For server errors, we control the Error object so I already had added
some context to that error object's message. Since we hide the message
in prod, it's nice not to have the raw message in DEV neither. We could
potentially split these into two errors for parity though.
2024-04-03 21:53:07 -04:00
Sebastian Markbåge 583eb6770d Emit Server Error Prefix in the .stack Property Too (#28738)
Follow up to #28684.

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

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

A possible alternative would be to use a nested error with a `cause`
like #28736 but that would need some more involved serializing since
this prefix is coming from the server. Perhaps as a separate attribute.
2024-04-03 21:52:54 -04:00
Ricky a5aedd1e15 Move console mocks to internal-test-utils (#28710)
Moving this to `internal-test-utils` so I can add helpers in the next PR
for:
- assertLogDev
- assertWarnDev
- assertErrorDev

Which will be exported from `internal-test-utils`. This isn't strictly
necessary, but it makes the factoring nicer, so internal-test-until
doesn't need to depend on `scripts/jest`.
2024-04-03 16:02:04 -04:00
Jan Kassens 20e710aeab Cleanup enableUseRefAccessWarning flag (#28699)
Cleanup enableUseRefAccessWarning flag

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

I think a new version of this could be to fully ban ref access during
render with an alternative API for the exceptional cases that today
require ref access during render.
2024-04-03 13:35:38 -04:00
Andrew Clark 3761acb42b Classes consume ref prop during SSR, too (#28731)
Same as #28719 but for SSR.
2024-04-03 12:55:57 -04:00
Jan Kassens 7a2609eedc Cleanup enableBigIntSupport flag (#28711)
Cleanup enableBigIntSupport flag
2024-04-03 09:25:02 -04:00
Jan Kassens 4e8121a75e Remove @providesModule remnants (#28720)
Remove @providesModule remnants

Removes `@providesModule` from the generated RN modules and CI
validation that no `@providesModule` is added which should no longer be
needed as this has been the case for years now.
2024-04-03 09:10:00 -04:00
Josh Story cb6dc7a6a0 [FB] use modern entrypoint in tests (#28724)
Removes the entrypoint hack in tests since we gate legacy mode tests now
2024-04-02 22:23:54 -07:00
Andrew Clark 131f020c09 Enable feature flags for v19 (#28647)
The canary channel now represents v19, so we can turn these flags on.
2024-04-02 23:33:13 -04:00
Andrew Clark dc545c8d6e Fix: Class components should "consume" ref prop (#28719)
When a ref is passed to a class component, the class instance is
attached to the ref's current property automatically. This different
from function components, where you have to do something extra to attach
a ref to an instance, like passing the ref to `useImperativeHandle`.

Existing class component code is written with the assumption that a ref
will not be passed through as a prop. For example, class components that
act as indirections often spread `this.props` onto a child component. To
maintain this expectation, we should remove the ref from the props
object ("consume" it) before passing it to lifecycle methods. Without
this change, much existing code will break because the ref will attach
to the inner component instead of the outer one.

This is not an issue for function components because we used to warn if
you passed a ref to a function component. Instead, you had to use
`forwardRef`, which also implements this "consuming" behavior.

There are a few places in the reconciler where we modify the fiber's
internal props object before passing it to userspace. The trickiest one
is class components, because the props object gets exposed in many
different places, including as a property on the class instance.

This was already accounted for when we added support for setting default
props on a lazy wrapper (i.e. `React.lazy` that resolves to a class
component).

In all of these same places, we will also need to remove the ref prop
when `enableRefAsProp` is on.

Closes #28602

---------

Co-authored-by: Jan Kassens <jan@kassens.net>
2024-04-02 23:15:04 -04:00
Sebastian Markbåge 8f55a6aa57 Move ReactDOMLegacy implementation into RootFB (#28656)
Only the FB entry point has legacy mode now so we can move the remaining
code in there.

Also enable disableLegacyMode in modern www builds since it doesn't
expose those entry points.

Now dependent on #28709.

---------

Co-authored-by: Josh Story <story@hey.com>
2024-04-02 21:56:23 -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
Josh Story 5998a77519 Reland #28672: Remove IndeterminateComponent (#28681)
This PR relands #28672 on top of the flag removal and the test
demonstrating a breakage in Suspense for legacy mode.

React has deprecated module pattern Function Components for many years
at this point. Supporting this pattern required React to have a concept
of an indeterminate component so that when a component first renders it
can turn into either a ClassComponent or a FunctionComponent depending
on what it returns. While this feature was deprecated and put behind a
flag it is still in stable. This change remvoes the flag, removes the
warnings, and removes the concept of IndeterminateComponent from the
React codebase.

While removing IndeterminateComponent type Seb and I discovered that we
needed a concept of IncompleteFunctionComponent to support Suspense in
legacy mode. This new work tag is only needed as long as legacy mode is
around and ideally any code that considers this tag will be excludable
from OSS builds once we land extra gates using `disableLegacyMode` flag.
2024-04-02 17:42:43 -07:00
Sebastian Markbåge 5fcaa0a832 Make ART Concurrent if Legacy Mode is disabled (#28662)
Pulling this out of #28657.

This runs react-art in concurrent mode if disableLegacyMode is true.
Effectively this means that the OSS version will be in concurrent mode
and the `.modern.js` version for Meta will be in concurrent mode, once
the flag flips for modern, but the `.classic.js` version for Meta will
be in legacy mode.

Updates flowing in from above flush synchronously so that they commit as
a unit. This also ensures that refs are resolved before the parent life
cycles. setStates deep in the tree will now be batched using "discrete"
priority but should still happen same task.
2024-04-02 15:00:30 -04:00
Joseph Savona 8cb6a1c034 [be] Remove unused, experimental getCacheSignal API (#28706)
Similar to #28698, this removes the `unstable_getCacheSignal()` API
since we don't intend to ship this to stable.
2024-04-02 10:54:31 -07:00
Sebastian Markbåge 48ec17b865 Differentiate null and undefined in Custom Elements - removing sets to undefined (#28716)
In React DOM, in general, we don't differentiate between `null` and
`undefined` because we expect to target DOM APIs. When we're setting a
property on a Custom Element, in the new heuristic, the goal is to allow
passing whatever data type instead of normalizing it. Switching between
`undefined` and `null` as an explicit value should therefore be
respected.

However, in this mode if `undefined` is used for the initial value, we
don't actually set the property at all. If passing `null` we will now
initialize it to the value `null`. Meaning `undefined` kind of
represents the default.

### Removing Properties

There is a pretty complex edge case which is what should happen when a
prop used to exist but was removed from the props object. This doesn't
have any kind of defined semantics. It really should mean - return to
"default". Because in the declarative world it means the same as if it
was just created - i.e. we can't just leave it as it was.

The closest might be `delete object.property` but that's not really the
intended way that properties on custom elements / classes are supposed
to operate. Additionally, for a property to even hit our heuristic it
must pass the `in` test and must exist to being with so the default must
have a value.

Since the point of these properties is to contain any kind of type,
there isn't really a conceptual default value. E.g. a numeric default
value might be zero `0` while a default string might be empty `""` and
default object might `null`. Additionally, the conceptual default can
really be initialized to anything. There's also varied precedence in the
ecosystem here and really no consensus. Anything we pick would be kind
of wrong, so we used to just pick `null`.

_The safest way to consume a Custom Element is to always pass the same
set of props._

JS does have a concept of a "default value" though and that is described
as the value `undefined`. That's why default argument / object property
initializers are initialized if the value is `undefined`.

The problem with using `undefined` as value is that [you shouldn't
actually ever set the value of a class property to
`undefined`](https://twitter.com/sebmarkbage/status/1774082540296388752).
A property should always be initialized to some value. It can't be left
missing and shouldn't be initialized to the value `undefined` for hidden
class optimizations. If we just mutate it to be `undefined` it would be
potentially bad for perf and shouldn't really be the value after
removing property - it should be returned to default.

Every property should really have a setter to be useful since it is what
is used to trigger reactivity when it changes. Sometimes you can just
use the properties passively when something else happens but most of the
time it should be a setter but to reach parity with DOM it should really
be always so that the active value can be normalized.

Those setters can have default argument initializers to represent what
the default value should be. Therefore Custom Element properties should
be used like this:

```js
class CustomElement extends HTMLElement {
  _textLabel = '';
  _price = 0;
  _items = null;
  
  constructor() {
    super();
  }
  set textLabel(value = '') {
    this._textLabel = value;
  }
  get textLabel() {
    return this._textLabel;
  }
  set price(value = 0) {
    this._price = value;
  }
  get price() {
    return this._price;
  }
  set items(value = null) {
    this._items = value;
  }
  get items() {
    return this._items;
  }
}
```

The default initializer can be used to initialize a value back to its
original default when `undefined` is passed to it. Therefore, we pass
`undefined`, not because we expect that to be the value of a property
but because that's the value that represents "return to default".

This fixes #28203 but not really for the reason specified in the issue.
We don't expect you to actually store the `undefined` value but to use a
setter to set the property to something else that represents the
default. When we initialize the element the first time, we won't set
anything if it's the value `undefined` so we assume that the property
initializers running in the constructor is going to set the same default
value as if we set the property to `undefined`.

cc @josepharhar
2024-04-02 11:48:27 -04:00
Jack Pope 4ecea96c55 Update RTR readme (#28705) 2024-04-02 11:41:31 -04:00
Jan Kassens ba5496d411 Hardcode enableLegacyFBSupport flag (#28701)
Hardcode enableLegacyFBSupport flag
2024-04-02 11:35:18 -04:00
Joseph Savona e3afd026c8 Remove reference to deleted <Cache> in un-linted file (#28715)
I missed this in #28698 bc the file isn't linted
2024-04-02 08:13:15 -07:00
Sebastian Silbermann 28fc980ef2 Cleanup enableNewBooleanProps (#28712) 2024-04-02 17:09:43 +02:00
Jan Kassens 7659c4d9e0 Remove dynamic www flag for disableInputAttributeSyncing (#28703)
Remove dynamic www flag for disableInputAttributeSyncing
2024-04-02 10:57:23 -04:00
Joseph Savona 7319c61b18 [be] Remove unshipped experimental <Cache> element type (#28698)
Removes the `<Cache />` element type since we're going with a simpler
caching strategy.
2024-04-02 07:57:08 -07:00
Jan Kassens c97564d7ac Upgrade flow to 0.232.0 (#28697)
Upgrade flow to 0.232.0
2024-04-02 10:40:03 -04:00
Jan Kassens 4eb241a94f Bump nvmrc to Node.js v18 (#28707)
Bump nvmrc to Node.js v18

Node.js v16 is long deprecated, seems like for v20 there's some more
stuff to fix.
2024-04-02 10:04:19 -04:00
Ricky 6e65010999 [tests] Disallow unasserted console.log (#28708)
Followup from https://github.com/facebook/react/pull/28693 and
https://github.com/facebook/react/pull/28680.

In CI, we fail the test for any unasserted console.log. In DEV, we don't
fail, but you can still use the matchers and we'll assert on them.
2024-04-01 17:45:49 -04:00
Jack Pope 8833338c8f Convert deprecated stalebot to github action (#28695)
## Summary

This repo uses [Stalebot](https://github.com/probot/stale) to manage
stale Issues and PRs. Stalebot hasn't been maintained for a couple of
years and is officially archived. The number of open Issues and PRs has
increased rapidly since early 2022. Some of this looks like issues with
Stalebot reliability where labels were not applied or close actions were
not taken even when meeting the criteria in the config.

In order to make it easier for maintainers to spend time on current
Issues and PRs, let's upgrade to the Github Stale Action. For now this
PR applies the same config to the new action but we can iterate on it as
needed. The goal is to clean up abandoned and no-longer-relevant
submissions, not to close Issues that describe active bugs or feedback.

## How did you test this change?

Added `debug-only: 'true'` to this PR so we can run the action and
review the logs before allowing the action to run on schedule. We may
see a large amount of label changes and close actions on the first run
as the action clears out previously ignored stale submissions.
2024-04-01 14:32:28 -04:00
Ricky 5ab97b7345 Land useModernStrictMode in www (#28696)
this has landed
2024-04-01 13:05:08 -04:00
Hendrik Liebau 93f91795a0 [Flight] Update stale blocked values in createModelResolver (#28669)
Alternative to #28620.

Instead of emitting lazy references to not-yet-emitted models in the
Flight Server, this fixes the observed issue in
https://github.com/unstubbable/ai-rsc-test/pull/1 by adjusting the lazy
model resolution in the Flight Client to update stale blocked root
models, before assigning them as chunk values. In addition, the element
props are not outlined anymore in the Flight Server to avoid having to
also handle their staleness in blocked elements.

fixes #28595
2024-04-01 12:37:27 -04:00
Jack Pope 95e6f032cf Clarify RTR native feature flags are fb specific (#28679)
Make it more clear that these flags aren't used in RN OSS.
- Rename
`packages/shared/forks/ReactFeatureFlags.test-renderer.native.js` to
`packages/shared/forks/ReactFeatureFlags.test-renderer.native-fb.js`
- Remove RN OSS build cases consuming the feature flags since there is
no RN OSS RTR build.
2024-04-01 10:56:28 -04:00
Jean-François Greffier 496fd3da5a [ESLint] Update README links to react.dev (#28692)
Update ESLint plugin README to redirect to https://react.dev for more
details (instead of legacy docs)
2024-04-01 10:52:34 -04:00
Ricky e9ae2c8f35 Clean up console.log tests (#28693)
Followups to https://github.com/facebook/react/pull/28680

One of these test don't need to use `console.log`. 

The others are specifically testing `console.log` behavior, so I added a
comment.
2024-04-01 10:50:48 -04:00
Sebastian Markbåge df95577db0 Finish cleaning up digest from onRecoverableError (#28686)
Don't need to track it separately on the captured value anymore.

Shouldn't be in the types.

I used a getter for the warning instead because Proxies are kind of
heavy weight options for this kind of warning. We typically use getters.
2024-03-30 18:32:20 -04:00
Timothy Yung 9f835e69ab Suppress console output in unit tests (#28680) 2024-03-30 09:36:23 -07:00
Sebastian Markbåge b9149cc6e6 Include regular stack trace in serialized errors from Fizz (#28684)
We previously only included the component stack.
    
Cleaned up the fields in Fizz server that wasn't using consistent hidden
classes in dev vs prod.

Added a prefix to errors serialized from server rendering. It can be a
bit confusing to see where this error came from otherwise since it
didn't come from elsewhere on the client. It's really kind of confusing
with other recoverable errors that happen on the client too.
2024-03-30 11:08:54 -04:00
Sebastian Markbåge 5d4b7587da Don't let error boundaries catch errors during hydration (#28675)
When an error boundary catches an error during hydration it'll try to
render the error state which will then try to hydrate that state,
causing hydration warnings.

When an error happens inside a Suspense boundary during hydration, we
instead let the boundary catch it and restart a client render from
there. However, when it's in the root we instead let it fail the root
and do the sync recovery pass. This didn't consider that we might hit an
error boundary first so this just skips the error boundary in that case.

We should probably instead let the root do a concurrent client render in
this same pass instead to unify with Suspense boundaries.
2024-03-29 16:43:22 -04:00
Jan Kassens 2aed507a76 Remove React.createFactory (#27798)
`React.createFactory` has been long deprecated. This removes it for the
next release.
2024-03-29 16:29:48 -04:00
Timothy Yung 13f35433bc Mock modules in tests using Module (#28678)
## Summary

Fixes a type validation error introduced in newer versions of Node.js
when calling `Module.prototype._compile` in our unit tests. (I tried but
have yet to pinpoint the precise change in Node.js that introduced this
vaildation.)

The specific error that currently occurs when running unit tests with
Node.js v18.16.1:

```
TypeError: The "mod" argument must be an instance of Module. Received an instance of Object

      80 |
      81 |     if (useServer) {
    > 82 |       originalCompile.apply(this, arguments);
         |                       ^
      83 |
      84 |       const moduleId: string = (url.pathToFileURL(filename).href: any);
      85 |
```

This fixes the type validation error by mocking modules using `new
Module()` instead of plain objects.

## How did you test this change?

Ran the unit tests successfully:

```
$ node --version
v18.16.1

$ yarn test
```
2024-03-29 13:19:54 -07:00
Jack Pope 6cd6ba703d Land enableNewBooleanProps everywhere (#28676)
Rolled out internally. Removing flag.
2024-03-29 16:02:32 -04:00
Timothy Yung 425f72bdd4 Align React Native OSS/Test Feature Flags (#28677)
## Summary

Makes a few changes to align React Native feature flags for open source
and internal test renderer configurations.

* Enable `enableSchedulingProfiler` for profiling builds.
* Align `ReactFeatureFlags.test-renderer.native.js` (with
`ReactFeatureFlags.native-fb.js`).
  * Enable `enableUseMemoCacheHook`.
  * Enable `enableFizzExternalRuntime`.
  * Disable `alwaysThrottleRetries`.

## How did you test this change?

Ran the following successfully:

```
$ yarn test
$ yarn flow native
$ yarn flow fabric
```
2024-03-29 12:47:00 -07:00
Jan Kassens 23b32d3f8d Test for ReactTestRenderer (#28674)
This is a repro for a breakage that #28672 would introduce for legacy
sync rendering.
2024-03-29 14:01:45 -04:00
Ricky 18812b645c Warn when using useFormState (#28668)
## Overview

useFormState has been replaced with useActionState. Warn when it's used.

Also removes the `experimental_useFormState` warnings.
2024-03-29 13:40:54 -04:00
Sophie Alpert 19c7c2929b Revert "Remove zoom from special cases list" (#28673)
Reverts facebook/react#26631

This got specced: https://github.com/w3c/csswg-drafts/pull/9699

I left msZoom because it seems plausible someone will still be using it
for backwards compat.
2024-03-29 10:39:12 -07:00
Andrey Lunyov eb510a3304 Land enableCustomElementPropertySupport for React 19 (#27450)
We've rolled out this flag internally on WWW. This PR removed flag
`enableCustomElementPropertySupport`

Test plan:
 -- `yarn test`

Co-authored-by: Ricky Hanlon <rickhanlonii@gmail.com>
2024-03-29 13:06:07 -04:00
Jan Kassens a73c3450e1 Remove module pattern function component support (flag only) (#28671)
Remove module pattern function component support (flag only)

> This is a redo of #27742, but only including the flag removal,
excluding further simplifications.

The module pattern

```
function MyComponent() {
  return {
    render() {
      return this.state.foo
    }
  }
}
```

has been deprecated for approximately 5 years now. This PR removes
support for this pattern.
2024-03-29 11:16:17 -04:00
Ricky f269074723 Revert "Remove module pattern function component support" (#28670)
This breaks internal tests, so must be something in the refactor. Since
it's the top commit let's revert and split into two PRs, one that
removes the flag and one that does the refactor, so we can find the bug.
2024-03-29 10:10:11 -04:00
Josh Story cc56bed38c Remove module pattern function component support (#27742)
The module pattern

```
function MyComponent() {
  return {
    render() {
      return this.state.foo
    }
  }
}
```

has been deprecated for approximately 5 years now. This PR removes
support for this pattern. It also simplifies a number of code paths in
particular related to the concept of `IndeterminateComponent` types.
2024-03-28 13:08:08 -07:00
Ricky 63651c49e0 Noop unstable_batchedUpdates (#28120)
## Overview

`unstable_batchedUpdates` is effectively a no-op outside of legacy mode,
this PR makes it an actual no-op outside legacy mode.
2024-03-28 14:15:37 -04:00