Commit Graph

462 Commits

Author SHA1 Message Date
Jan Kassens
d8c1fa6b0b
Add infinite update loop detection (#28279)
This is a partial redo of https://github.com/facebook/react/pull/26625.
Since that was unlanded due to some detected breakages. This now
includes a feature flag to be careful in rolling this out.
2024-02-09 11:14:37 -05:00
Sebastian Markbåge
5c08662301
Add enableServerComponentKeys to NEXT_MAJOR (#28259) 2024-02-07 15:21:59 -05:00
Josh Story
2bc7d336ae
Add flag to disable caching behavior of React.cache on the client (#28250)
Adds a feature flag to control whether the client cache function is just
a passthrough. before we land breaking changes for the next major it
will be off and then we can flag it on when we want to break it.

flag is off for OSS for now and on elsewhere (though the parent flag
enableCache is off in some cases)
2024-02-05 16:32:03 -08:00
dan
472854820b
[Flight] Delete Server Context (#28225)
Server Context was never documented, and has been deprecated in
https://github.com/facebook/react/pull/27424.

This PR removes it completely, including the implementation code.

Notably, `useContext` is removed from the shared subset, so importing it
from a React Server environment would now should be a build error in
environments that are able to enforce that.
2024-02-05 22:39:15 +00:00
Sebastian Markbåge
95ec128399
[Flight] Support Keyed Server Components (#28123)
Conceptually a Server Component in the tree is the same as a Client
Component.

When we render a Server Component with a key, that key should be used as
part of the reconciliation process to ensure the children's state are
preserved when they move in a set. The key of a child should also be
used to clear the state of the children when that key changes.

Conversely, if a Server Component doesn't have a key it should get an
implicit key based on the slot number. It should not inherit the key of
its children since the children don't know if that would collide with
other keys in the set the Server Component is rendered in.

A Client Component also has an identity based on the function's
implementation type. That mainly has to do with the state (or future
state after a refactor) that Component might contain. To transfer state
between two implementations it needs to be of the same state type. This
is not a concern for a Server Components since they never have state so
identity doesn't matter.

A Component returns a set of children. If it returns a single child,
that's the same as returning a fragment of one child. So if you
conditionally return a single child or a fragment, they should
technically reconcile against each other.

The simple way to do this is to simply emit a Fragment for every Server
Component. That would be correct in all cases. Unfortunately that is
also unfortunate since it bloats the payload in the common cases. It
also means that Fiber creates an extra indirection in the runtime.

Ideally we want to fold Server Component aways into zero cost on the
client. At least where possible. The common cases are that you don't
specify a key on a single return child, and that you do specify a key on
a Server Component in a dynamic set.

The approach in this PR treats a Server Component that returns other
Server Components or Lazy Nodes as a sequence that can be folded away.
I.e. the parts that don't generate any output in the RSC payload.
Instead, it keeps track of their keys on an internal "context". Which
gets reset after each new reified JSON node gets rendered.

Then we transfer the accumulated keys from any parent Server Components
onto the child element. In the simple case, the child just inherits the
key of the parent.

If the Server Component itself is keyless but a child isn't, we have to
add a wrapper fragment to ensure that this fragment gets the implicit
key but we can still use the key to reset state. This is unusual though
because typically if you keyed something it's because it was already in
a fragment.

In the case a Server Component is keyed but forks its children using a
fragment, we need to key that fragment so that the whole set can move
around as one. In theory this could be flattened into a parent array but
that gets tricky if something suspends, because then we can't send the
siblings early.

The main downside of this approach is that switching between single
child and fragment in a Server Component isn't always going to reconcile
against each other. That's because if we saw a single child first, we'd
have to add the fragment preemptively in case it forks later. This
semantic of React isn't very well known anyway and it might be ok to
break it here for pragmatic reasons. The tests document this
discrepancy.

Another compromise of this approach is that when combining keys we don't
escape them fully. We instead just use a simple `,` separated concat.
This is probably good enough in practice. Additionally, since we don't
encode the implicit 0 index slot key, you can move things around between
parents which shouldn't really reconcile but does. This keeps the keys
shorter and more human readable.
2024-02-05 09:33:35 -08:00
Ricky
3d1da1f9ab
Remove createRootStrictEffectsByDefault flag (#28102)
There's no need to separate strict mode from strict effects mode any
more.

I didn't clean up the `StrictEffectMode` fiber flag, because it's used
to prevent strict effects in legacy mode. I could replace those checks
with `LegacyMode` checks, but when we remove legacy mode, we can remove
that flag and condense them into one StrictMode flag away.
2024-02-01 14:54:20 -05:00
Ricky
4d6c47baa3
Clean up experimental flags (#28116)
## Overview

Adds a new global to disambiguate experimental flags that we intend to
land when we can make breaking changes.
2024-01-29 14:03:39 -05:00
Ricky
766eac46bb
Remove outdated enableSchedulerDebugging flag (#28101)
This flag was moved to the scheduler feature flags, so these flags don't
do anything.
2024-01-26 16:53:01 -05:00
Sebastian Markbåge
8b8d265bd9
[Flight] Wire up async_hooks in Node.js DEV for inspecting Promises (#27840)
This wires up the use of `async_hooks` in the Node build (as well as the
Edge build when a global is available) in DEV mode only. This will be
used to track debug info about what suspended during an RSC pass.

Enabled behind a flag for now.
2023-12-15 21:38:01 -05:00
Jan Kassens
0cdfef19b9
Add feature flags for expiration times (#27821)
It seems worthwhile to me to run a test to experiment with different
expiration times. This moves the expiration times for scheduler and
reconciler into FeatureFlags for the facebook build. Non-facebook should
not be affected by these changes.
2023-12-11 09:58:18 -05:00
Jan Kassens
1a65d036ef
[cleanup] remove enableHostSingletons feature flag (#27583)
The flag is enabled everywhere, I think we can remove it now.
2023-11-16 17:42:03 -05:00
Jan Kassens
593ecee66a
Add a feature flag to enable expiration of retry lanes (#27694)
An attempt to see if we can bring back expiration of retry lanes to
avoid cases resolving Suspense can be starved by frequent updates.

In the past, this caused increase browser crashes, but a lot of time has
passed since then. Just trying if we can re-enable this.

Old PR that reverted adding the timeout:
https://github.com/facebook/react/pull/21300
2023-11-14 10:15:17 -05:00
Tianyu Yao
52d542ad6d
Enable enableUnifiedSyncLane (#27646)
<!--
  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?
-->
The flag has been tested internally on WWW, should be good to set to
true for OSS. Added a dynamic flag for fb RN.

## 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
2023-11-07 16:45:33 -08:00
Sebastian Markbåge
1fc58281af
Disable ServerContext in canary (#27474)
We previously added a warning in #27424. This just removes it from
canary/stable channels but keeps it in experimental for now.
2023-10-11 12:13:09 -04:00
Andrew Clark
be67db46b6
Add optional initialValue argument to useDeferredValue (#27500)
Adds a second argument to useDeferredValue called initialValue:

```js
const value = useDeferredValue(finalValue, initialValue);
```

During the initial render of a component, useDeferredValue will return
initialValue. Once that render finishes, it will spawn an additional
render to switch to finalValue.

This same sequence should occur whenever the hook is hidden and revealed
again, i.e. by a Suspense or Activity, though this part is not yet
implemented.

When initialValue is not provided, useDeferredValue has no effect during
initial render, but during an update, it will remain on the previous
value, then spawn an additional render to switch to the new value. (This
is the same behavior that exists today.)

During SSR, initialValue is always used, if provided.

This feature is currently behind an experimental flag. We plan to ship
it in a non-breaking release.
2023-10-10 16:39:02 -04: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
Andrew Clark
bfefb22842
Upgrade Server Actions to canary (#27459)
Upgrades the stability of Server Actions from experimental to canary.

- Turns on enableAsyncActions and enableFormActions
- Removes "experimental_" prefix from useOptimistic, useFormStatus, and
useFormState
2023-10-04 14:51:36 -04:00
Sebastian Markbåge
843ec07021
[Flight] Taint APIs (#27445)
This lets a registered object or value be "tainted", which we block from
crossing the serialization boundary. It's only allowed to stay
in-memory.

This is an extra layer of protection against mistakes of transferring
data from a data access layer to a client. It doesn't provide perfect
protection, because it doesn't trace through derived values and
substrings. So it shouldn't be used as the only security layer but more
layers are better.

`taintObjectReference` is for specific object instances, not any nested
objects or values inside that object. It's useful to avoid specific
objects from getting passed as is. It ensures that you don't
accidentally leak values in a specific context. It can be for security
reasons like tokens, privacy reasons like personal data or performance
reasons like avoiding passing large objects over the wire.

It might be privacy violation to leak the age of a specific user, but
the number itself isn't blocked in any other context. As soon as the
value is extracted and passed specifically without the object, it can
therefore leak.

`taintUniqueValue` is useful for high entropy values such as hashes,
tokens or crypto keys that are very unique values. In that case it can
be useful to taint the actual primitive values themselves. These can be
encoded as a string, bigint or typed array. We don't currently check for
this value in a substring or inside other typed arrays.

Since values can be created from different sources they don't just
follow garbage collection. In this case an additional object must be
provided that defines the life time of this value for how long it should
be blocked. It can be `globalThis` for essentially forever, but that
risks leaking memory for ever when you're dealing with dynamic values
like reading a token from a database. So in that case the idea is that
you pass the object that might end up in cache.

A request is the only thing that is expected to do any work. The
principle is that you can derive values from out of a tainted
entry during a request. Including stashing it in a per request cache.
What you can't do is store a derived value in a global module level
cache. At least not without also tainting the object.
2023-10-02 13:55:39 -04: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
Sophie Alpert
7f6201889e
Ship diffInCommitPhase (#27409)
Performance tests at Meta showed neutral results.
2023-09-22 20:24:42 -07:00
Sebastian Markbåge
ac1a16c67e
Add Postpone API (#27238)
This adds an experimental `unstable_postpone(reason)` API.

Currently we don't have a way to model effectively an Infinite Promise.
I.e. something that suspends but never resolves. The reason this is
useful is because you might have something else that unblocks it later.
E.g. by updating in place later, or by client rendering.

On the client this works to model as an Infinite Promise (in fact,
that's what this implementation does). However, in Fizz and Flight that
doesn't work because the stream needs to end at some point. We don't
have any way of knowing that we're suspended on infinite promises. It's
not enough to tag the promises because you could await those and thus
creating new promises. The only way we really have to signal this
through a series of indirections like async functions, is by throwing.
It's not 100% safe because these values can be caught but it's the best
we can do.

Effectively `postpone(reason)` behaves like a built-in [Catch
Boundary](https://github.com/facebook/react/pull/26854). It's like
`raise(Postpone, reason)` except it's built-in so it needs to be able to
be encoded and caught by Suspense boundaries.

In Flight and Fizz these behave pretty much the same as errors. Flight
just forwards it to retrigger on the client. In Fizz they just trigger
client rendering which itself might just postpone again or fill in the
value. The difference is how they get logged.

In Flight and Fizz they log to `onPostpone(reason)` instead of
`onError(error)`. This log is meant to help find deopts on the server
like finding places where you fall back to client rendering. The reason
that you pass in is for that purpose to help the reason for any deopts.

I do track the stack trace in DEV but I don't currently expose it to
`onPostpone`. This seems like a limitation. It might be better to expose
the Postpone object which is an Error object but that's more of an
implementation detail. I could also pass it as a second argument.

On the client after hydration they don't get passed to
`onRecoverableError`. There's no global `onPostpone` API to capture
postponed things on the client just like there's no `onError`. At that
point it's just assumed to be intentional. It doesn't have any `digest`
or reason passed to the client since it's not logged.

There are some hacky solutions that currently just tries to reuse as
much of the existing code as possible but should be more properly
implemented.
- Fiber is currently just converting it to a fake Promise object so that
it behaves like an infinite Promise.
- Fizz is encoding the magic digest string `"POSTPONE"` in the HTML so
we know to ignore it but it should probably just be something neater
that doesn't share namespace with digests.

Next I plan on using this in the `/static` entry points for additional
features.

Why "postpone"? It's basically a synonym to "defer" but we plan on using
"defer" for other purposes and it's overloaded anyway.
2023-08-17 13:26:14 -04:00
Sebastian Markbåge
d9c333199e
[Flight] Add Serialization of Typed Arrays / ArrayBuffer / DataView (#26954)
This uses the same mechanism as [large
strings](https://github.com/facebook/react/pull/26932) to encode chunks
of length based binary data in the RSC payload behind a flag.

I introduce a new BinaryChunk type that's specific to each stream and
ways to convert into it. That's because we sometimes need all chunks to
be Uint8Array for the output, even if the source is another array buffer
view, and sometimes we need to clone it before transferring.

Each type of typed array is its own row tag. This lets us ensure that
the instance is directly in the right format in the cached entry instead
of creating a wrapper at each reference. Ideally this is also how
Map/Set should work but those are lazy which complicates that approach a
bit.

We assume both server and client use little-endian for now. If we want
to support other modes, we'd convert it to/from little-endian so that
the transfer protocol is always little-endian. That way the common
clients can be the fastest possible.

So far this only implements Server to Client. Still need to implement
Client to Server for parity.

NOTE: This is the first time we make RSC effectively a binary format.
This is not compatible with existing SSR techniques which serialize the
stream as unicode in the HTML. To be compatible, those implementations
would have to use base64 or something like that. Which is what we'll do
when we move this technique to be built-in to Fizz.
2023-06-29 13:16:12 -04:00
Noah Lemen
80d9a40114
Remove useMutableSource (#27011)
## Summary

This PR cleans up `useMutableSource`. This has been blocked by a
remaining dependency internally at Meta, but that has now been deleted.

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

## How did you test this change?

```
yarn flow
yarn lint
yarn test --prod
```

<!--
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.
-->
2023-06-27 12:45:46 -04:00
Tianyu Yao
254cbdbd6d
Add a temporary internal option to disable double useEffect in legacy strict mode (#26914)
<!--
  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?
-->
We are upgrading React 17 codebase to React18, and `StrictMode` has been
great for surfacing potential production bugs on React18 for class
components. There are non-trivial number of test failures caused by
double `useEffect` in StrictMode. To prioritize surfacing and fixing
issues that will break in production now, we need a flag to turn off
double `useEffect` for now in StrictMode temporarily. This is a
Meta-only hack for rolling out `createRoot` and we will fast follow to
remove it and use full strict mode.

## 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.
-->
jest
2023-06-21 11:14:57 -07:00
Ricky
018c58c9c6
Clean up enableSyncDefaultUpdates flag a bit (#26858)
## Overview

Does a few things:
- Renames `enableSyncDefaultUpdates` to
`forceConcurrentByDefaultForTesting`
- Changes the way it's used so it's dead-code eliminated separate from
`allowConcurrentByDefault`
- Deletes a bunch of the gated code

The gates that are deleted are unnecessary now. We were keeping them
when we originally thought we would come back to being concurrent by
default. But we've shifted and now sync-by default is the desired
behavior long term, so there's no need to keep all these forked tests
around.

I'll follow up to delete more of the forked behavior if possible.
Ideally we wouldn't need this flag even if we're still using
`allowConcurrentByDefault`.
2023-06-01 09:24:56 -04:00
Andrew Clark
7ce765ec32
Clean up enableUseHook flag (#26707)
This has been statically enabled everywhere for months.
2023-04-23 14:50:17 -04:00
Andrew Clark
d73d7d5908
Add alwaysThrottleRetries flag (#26685)
This puts the change introduced by #26611 behind a flag until Meta is
able to roll it out. Disabling the flag reverts back to the old
behavior, where retries are throttled if there's still data remaining in
the tree, but not if all the data has finished loading.

The new behavior is still enabled in the public builds.
2023-04-20 14:23:22 -04:00
Sebastian Markbåge
c826dc50de
Add (Client) Functions as Form Actions (#26674)
This lets you pass a function to `<form action={...}>` or `<button
formAction={...}>` or `<input type="submit formAction={...}>`. This will
behave basically like a `javascript:` URL except not quite implemented
that way. This is a convenience for the `onSubmit={e => {
e.preventDefault(); const fromData = new FormData(e.target); ... }`
pattern.

You can still implement a custom `onSubmit` handler and if it calls
`preventDefault`, it won't invoke the action, just like it would if you
used a full page form navigation or javascript urls. It behaves just
like a navigation and we might implement it with the Navigation API in
the future.

Currently this is just a synchronous function but in a follow up this
will accept async functions, handle pending states and handle errors.

This is implemented by setting `javascript:` URLs, but these only exist
to trigger an error message if something goes wrong instead of
navigating away. Like if you called `stopPropagation` to prevent React
from handling it or if you called `form.submit()` instead of
`form.requestSubmit()` which by-passes the `submit` event. If CSP is
used to ban `javascript:` urls, those will trigger errors when these
URLs are invoked which would be a different error message but it's still
there to notify the user that something went wrong in the plumbing.

Next up is improving the SSR state with action replaying and progressive
enhancement.
2023-04-19 16:31:08 -04:00
Andrew Clark
cd2b79dedd
Initial (client-only) async actions support (#26621)
Implements initial (client-only) support for async actions behind a
flag. This is an experimental feature and the design isn't completely
finalized but we're getting closer. It will be layered alongside other
features we're working on, so it may not feel complete when considered
in isolation.

The basic description is you can pass an async function to
`startTransition` and all the transition updates that are scheduled
inside that async function will be grouped together. The `isPending`
flag will be set to true immediately, and only set back to false once
the async action has completed (as well as all the updates that it
triggers).

The ideal behavior would be that all updates spawned by the async action
are automatically inferred and grouped together; however, doing this
properly requires the upcoming (stage 2) Async Context API, which is not
yet implemented by browsers. In the meantime, we will fake this by
grouping together all transition updates that occur until the async
function has terminated. This can lead to overgrouping between unrelated
actions, which is not wrong per se, just not ideal.

If the `useTransition` hook is removed from the UI before an async
action has completed — for example, if the user navigates to a new page
— subsequent transitions will no longer be grouped with together with
that action.

Another consequence of the lack of Async Context is that if you call
`setState` inside an action but after an `await`, it must be wrapped in
`startTransition` in order to be grouped properly. If we didn't require
this, then there would be no way to distinguish action updates from
urgent updates caused by user input, too. This is an unfortunate footgun
but we can likely detect the most common mistakes using a lint rule.

Once Async Context lands in browsers, we can start warning in dev if we
detect an update that hasn't been wrapped in `startTransition`. Then,
longer term, once the feature is ubiquitous, we can rely on it for real
and allow you to call `setState` without the additional wrapper.

Things that are _not_ yet implemented in this PR, but will be added as
follow ups:

- Support for non-hook form of `startTransition`
- Canceling the async action scope if the `useTransition` hook is
deleted from the UI
- Anything related to server actions
2023-04-19 13:33:11 -04:00
Samuel Susla
7b0642bb98
Remove revertRemovalOfSiblingPrerendering killswitch (#26549)
removal of sibling prerendering has been rolled out at Meta. We can
delete the flag now.
2023-04-12 21:05:17 -04:00
Sebastian Markbåge
ca41adb8c1
Diff properties in the commit phase instead of generating an update payload (#26583)
This removes the concept of `prepareUpdate()`, behind a flag.

React Native already does everything in the commit phase, but generates
a temporary update payload before applying it.

React Fabric does it both in the render phase. Now it just moves it to a
single host config.

For DOM I forked updateProperties into one that does diffing and
updating in one pass vs just applying a pre-diffed updatePayload.

There are a few downsides of this approach:

- If only "children" has changed, we end up scheduling an update to be
done in the commit phase. Since we traverse through it anyway, it's
probably not much extra.
- It does more work in the commit phase so for a large tree that is
mostly unchanged, it'll stall longer.
- It does some extra work for special cases since that work happens if
anything has changed. We no longer have a deep bailout.
- The special cases now have to each replicate the "clean up old props"
loop, leading to extra code.

The benefit is that this doesn't allocate temporary extra objects
(possibly multiple per element if the array has to resize). It's less
work overall. It also gives us an option to reuse this function for a
sync render optimization.

Another benefit is that if we do the loop in the commit phase I can do
further optimizations by reading all props that I need for special cases
in that loop instead of polymorphic reads from props. This is what I'd
like to do in future refactors that would be stacked on top of this
change.
2023-04-10 19:09:28 -04:00
Jan Kassens
da94e8b24a
Revert "Cleanup enableSyncDefaultUpdate flag (#26236)" (#26528)
This reverts commit b2ae9ddb3b.

While the feature flag is fully rolled out, these tests are also testing
behavior set with an unstable flag on root, which for now we want to
preserve.

Not sure if there's a better way then adding a dynamic feature flag to
the www build?
2023-04-04 10:08:14 -04:00
Andrew Clark
09c8d25633
Move update scheduling to microtask (#26512)
When React receives new input (via `setState`, a Suspense promise
resolution, and so on), it needs to ensure there's a rendering task
associated with the update. Most of this happens
`ensureRootIsScheduled`.

If a single event contains multiple updates, we end up running the
scheduling code once per update. But this is wasteful because we really
only need to run it once, at the end of the event (or in the case of
flushSync, at the end of the scope function's execution).

So this PR moves the scheduling logic to happen in a microtask instead.
In some cases, we will force it run earlier than that, like for
`flushSync`, but since updates are batched by default, it will almost
always happen in the microtask. Even for discrete updates.

In production, this should have no observable behavior difference. In a
testing environment that uses `act`, this should also not have a
behavior difference because React will push these tasks to an internal
`act` queue.

However, tests that do not use `act` and do not simulate an actual
production environment (like an e2e test) may be affected. For example,
before this change, if a test were to call `setState` outside of `act`
and then immediately call `jest.runAllTimers()`, the update would be
synchronously applied. After this change, that will no longer work
because the rendering task (a timer, in this case) isn't scheduled until
after the microtask queue has run.

I don't expect this to be an issue in practice because most people do
not write their tests this way. They either use `act`, or they write
e2e-style tests.

The biggest exception has been... our own internal test suite. Until
recently, many of our tests were written in a way that accidentally
relied on the updates being scheduled synchronously. Over the past few
weeks, @tyao1 and I have gradually converted the test suite to use a new
set of testing helpers that are resilient to this implementation detail.

(There are also some old Relay tests that were written in the style of
React's internal test suite. Those will need to be fixed, too.)

The larger motivation behind this change, aside from a minor performance
improvement, is we intend to use this new microtask to perform
additional logic that doesn't yet exist. Like inferring the priority of
a custom event.
2023-03-31 13:04:08 -04:00
Andrew Clark
8310854ceb
Clean up enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay (#26521)
This flag is already enabled everywhere except for www, which is blocked
by a few tests that assert on the old behavior. Once www is ready, I'll
land this.
2023-03-31 10:25:58 -04:00
Ricky
ca01f359b9
Remove skipUnmountedBoundaries (#26489)
# Overview

Landing this flag internally, will test this PR in React Native before
merging.
2023-03-30 20:58:13 -04:00
Andrew Clark
2d51251e60
Clean up deferRenderPhaseUpdateToNextBatch (#26511)
This is a change to some undefined behavior that we though we would do
at one point but decided not to roll out. It's already disabled
everywhere, so this just deletes the branch from the implementation and
the tests.
2023-03-30 14:10:19 -04:00
Ricky
41b4714f19
Remove disableNativeComponentFrames (#26490)
## Overview

I'm landing this flag internally so we can delete this
2023-03-28 09:46:26 -04:00
Jan Kassens
8342a09927
Remove unused feature flag disableSchedulerTimeoutBasedOnReactExpirationTime (#26488)
Easy removal as it's completely unused as @rickhanlonii noticed.
2023-03-27 17:52:02 +02:00
Andrew Clark
12a1d140e3
Don't prerender siblings of suspended component (#26380)
Today if something suspends, React will continue rendering the siblings
of that component.

Our original rationale for prerendering the siblings of a suspended
component was to initiate any lazy fetches that they might contain. This
was when we were more bullish about lazy fetching being a good idea some
of the time (when combined with prefetching), as opposed to our latest
thinking, which is that it's almost always a bad idea.

Another rationale for the original behavior was that the render was I/O
bound, anyway, so we might as do some extra work in the meantime. But
this was before we had the concept of instant loading states: when
navigating to a new screen, it's better to show a loading state as soon
as you can (often a skeleton UI), rather than delay the transition.
(There are still cases where we block the render, when a suitable
loading state is not available; it's just not _all_ cases where
something suspends.) So the biggest issue with our existing
implementation is that the prerendering of the siblings happens within
the same render pass as the one that suspended — _before_ the loading
state appears.

What we should do instead is immediately unwind the stack as soon as
something suspends, to unblock the loading state.

If we want to preserve the ability to prerender the siblings, what we
could do is schedule special render pass immediately after the fallback
is displayed. This is likely what we'll do in the future. However, in
the new implementation of `use`, there's another reason we don't
prerender siblings: so we can preserve the state of the stack when
something suspends, and resume where we left of when the promise
resolves without replaying the parents. The only way to do this
currently is to suspend the entire work loop. Fiber does not currently
support rendering multiple siblings in "parallel". Once you move onto
the next sibling, the stack of the previous sibling is discarded and
cannot be restored. We do plan to implement this feature, but it will
require a not-insignificant refactor.

Given that lazy data fetching is already bad for performance, the best
trade off for now seems to be to disable prerendering of siblings. This
gives us the best performance characteristics when you're following best
practices (i.e. hoist data fetches to Server Components or route
loaders), at the expense of making an already bad pattern a bit worse.

Later, when we implement resumable context stacks, we can reenable
sibling prerendering. Though even then the use case will mostly be to
prerender the CPU-bound work, not lazy fetches.
2023-03-21 10:24:56 -04:00
Sebastian Markbåge
cfc1274e3b
Disable IE innerHTML workaround behind a flag (#26390)
We don't need this workaround for SVG anymore and we don't need to
workaround MSApp's security model since Windows 10.
2023-03-14 23:27:04 -04:00
Sebastian Markbåge
2788d0d8dd
Allow empty string to be passed to formAction (#26379)
We disallow empty strings for `href` and `src` since they're common
mistakes that end up loading the current page as a preload, image or
link. We also disallow it for `action`. You have to pass `null` which is
the same.

However, for `formAction` passing `null` is not the same as passing
empty string. Passing empty string overrides the form's action to be the
current page even if the form's action was set to something else.
There's no easy way to express the same thing `#` show up in the user
visible URLs and `?` clears the search params.

Since this is also not a common mistake, we can just allow this.
2023-03-13 14:28:17 -04:00
Josh Story
1f1f8eb559
[Float][Fizz][Fiber]: Refactor <style> Resource implementation to group on flush (#26280)
There is a problem with <style> as resource. For css-in-js libs there
may be an very large number of these hoistables being created. The
number of style tags can grow quickly and to help reduce the prevalence
of this FIzz now aggregates all style tags for a given precedence into a
single tag. The client can 'hydrate' against these compound tags but
currently on the client insertions are done individually.

additionally drops the implementation where style tags are embedding in
a template for one where `media="not all"` is set. The idea is to have
the browser construct the underlying stylesheet eagerly which does not
happen if the tag is embedded in a template

Key Decision:
One choice made in this PR is that we flush style tags eagerly even if a
boundary is blocked that is the only thing that depends on that style
rule. The reason we are starting with this implementation is that it
allows a very condensed representation of the style resources. If we
tracked which rules were used in which boundaries we would need a style
resource for every rendered <style> tag. This could be problematic for
css-in-js libs that might render hundreds or thousands of style tags.
The tradeoff here is we slightly delay content reveal in some cases (we
send extra bytes) but we have fewer DOM tags and faster SSR runtime
2023-03-03 12:50:35 -08:00
Jan Kassens
b2ae9ddb3b
Cleanup enableSyncDefaultUpdate flag (#26236)
This feature flag is enabled everywhere.
2023-02-27 14:04:02 -05:00
Jan Kassens
6b30832666
Upgrade prettier (#26081)
The old version of prettier we were using didn't support the Flow syntax
to access properties in a type using `SomeType['prop']`. This updates
`prettier` and `rollup-plugin-prettier` to the latest versions.

I added the prettier config `arrowParens: "avoid"` to reduce the diff
size as the default has changed in Prettier 2.0. The largest amount of
changes comes from function expressions now having a space. This doesn't
have an option to preserve the old behavior, so we have to update this.
2023-01-31 08:25:05 -05:00
Jan Kassens
1f5ce59dd7
[cleanup] fully roll out warnAboutSpreadingKeyToJSX (#26080)
I fully enabled this flag internally now and unless I see complications,
we should be able to clean this up in the code.
2023-01-30 15:25:24 -05:00
Jan Kassens
ee85098019
[cleanup] remove deletedTreeCleanUpLevel feature flag (#25529)
I noticed this was an experiment concluded 16 months ago (#21679) that
this extra work is beneficial
to break up cycles leaking memory in product code.
2023-01-17 11:03:29 -05:00
Jan Kassens
0fce6bb498
[cleanup] remove feature flags warnAboutDefaultPropsOnFunctionComponents and warnAboutStringRefs (#25980)
These feature flags are fully rolled out and easy to clean up. Let's
remove them!
2023-01-11 12:19:46 -05:00
Jan Kassens
a48e54f2b7
[cleanup] remove old feature flag warnAboutDeprecatedLifecycles (#25978)
This feature flag was always set to true, we can easily clean it up.
2023-01-10 15:30:42 -05:00
Tianyu Yao
5379b6123f
Batch sync, default and continuous lanes (#25700)
<!--
  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 debug-test --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?
-->
This is the other approach for unifying default and sync lane
https://github.com/facebook/react/pull/25524.
The approach in that PR is to merge default and continuous lane into the
sync lane, and use a new field to track the priority. But there are a
couple places that field will be needed, and it is difficult to
correctly reset the field when there is no sync lane.

In this PR we take the other approach that doesn't remove any lane, but
batch them to get the behavior we want.


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

Co-authored-by: Andrew Clark <hi@andrewclark.io>
2023-01-05 15:21:35 -08:00
Sebastian Markbåge
84a0a171ea
Rename experimental useEvent to useEffectEvent (#25881)
We originally had grand plans for using this Event concept for more but
now it's only meant to be used in combination with effects.

It's an Event in the FRP terms, that is triggered from an Effect.
Technically it can also be from another function that itself is
triggered from an existing side-effect but that's kind of an advanced
case.

The canonical case is an effect that triggers an event:

```js
const onHappened = useEffectEvent(() => ...);
useEffect(() => {
  onHappened();
}, []);
```
2022-12-14 15:08:29 -05:00
Jan Kassens
420f0b7fa1
Remove Reconciler fork (1/2) (#25774)
We've heard from multiple contributors that the Reconciler forking
mechanism was confusing and/or annoying to deal with. Since it's
currently unused and there's no immediate plans to start using it again,
this removes the forking.

Fully removing the fork is split into 2 steps to preserve file history:

**This PR**
- remove `enableNewReconciler` feature flag.
- remove `unstable_isNewReconciler` export
- remove eslint rules for cross fork imports
- remove `*.new.js` files and update imports
- merge non-suffixed files into `*.old` files where both exist
(sometimes types were defined there)

**#25775**
- rename `*.old` files
2022-12-01 23:06:25 -05:00
Sebastian Markbåge
7b17f7bbf3
Enable warning for defaultProps on function components for everyone (#25699)
This also fixes a gap where were weren't warning on memo components.
2022-11-17 12:22:23 -05:00
Sebastian Silbermann
6fb8133ed3
Turn on string ref deprecation warning for everybody (not codemoddable) (#25383)
## Summary
 
Alternate to https://github.com/facebook/react/pull/25334 without any
prod runtime changes i.e. the proposed codemod in
https://github.com/reactjs/rfcs/blob/createlement-rfc/text/0000-create-element-changes.md#deprecate-string-refs-and-remove-production-mode-_owner-field
would not work.

## How did you test this change?

- [x] CI
- [x] `yarn test` with and without `warnAboutStringRefs`
2022-11-16 19:15:57 -05:00
Sebastian Markbåge
07f46ecf2e
Turn on key spread warning in jsx-runtime for everyone (#25697)
This improves the error message a bit and ensures that we recommend
putting the key first, not last, which ensures that the faster
`jsx-runtime` is used.

This only affects the modern "automatic" JSX transform.
2022-11-16 18:57:50 -05:00
mofeiZ
6883d79445
[ServerRenderer] Setup for adding data attributes streaming format (#25567) 2022-11-01 12:04:50 -04:00
Sebastian Markbåge
e7c5af45ce
Update cache() and use() to the canary aka next channel (#25502)
Testing what it would look like to move this to the `next` channel.
2022-10-23 23:20:52 -04:00
Sebastian Markbåge
65e32e58b6
Add fetch Instrumentation to Dedupe Fetches (#25516)
* Add fetch instrumentation in cached contexts

* Avoid unhandled rejection errors for Promises that we intentionally ignore

In the final passes, we ignore the newly generated Promises and use
the previous ones. This ensures that if those generate errors, that we
intentionally ignore those.

* Add extra fetch properties if there were any
2022-10-19 18:37:00 -04:00
Samuel Susla
987292815c
Remove feature flag enableStrictEffects (#25387) 2022-10-19 10:57:09 +01:00
Andrew Clark
9cdf8a99ed
[Codemod] Update copyright header to Meta (#25315)
* Facebook -> Meta in copyright

rg --files | xargs sed -i 's#Copyright (c) Facebook, Inc. and its affiliates.#Copyright (c) Meta Platforms, Inc. and affiliates.#g'

* Manual tweaks
2022-10-18 11:19:24 -04:00
Andrew Clark
500bea532d
Add option to load Fizz runtime from external file (#25499)
* Add feature flag for external Fizz runtime

Only enabled for www for now

* Add option to load Fizz runtime from external file

When unstable_externalRuntimeSrc is provided, React will inject a script
tag that points to the provided URL.

Then, instead of emitting inline scripts, the Fizz stream will emit
HTML nodes with data attributes that encode the instructions. The
external runtime will detect these with a mutation observer and
translate them into runtime commands. This part isn't implemented in 
this PR, though — all this does is set up the option to use 
an external runtime, and inject the script tag.

The external runtime is injected at the same time as bootstrap scripts.
2022-10-17 17:57:59 -04:00
Josh Story
2cf4352e1c
Implement HostSingleton Fiber type (#25426) 2022-10-11 08:42:42 -07:00
Samuel Susla
abbbdf4cec
Put modern StrictMode behind a feature flag (#25365)
* Put modern StrictMode behind a feature flag

* Remove unneeded flag
2022-09-30 17:06:11 +01:00
Vic Graf
20a257c259
Refactor: more word doubles removed (#25352) 2022-09-29 09:57:49 -04:00
Lauren Tan
c91a1e03be
experimental_useEvent (#25229)
This commit adds a new hook `useEvent` per the RFC [here](https://github.com/reactjs/rfcs/pull/220), gated as experimental. 

Co-authored-by: Rick Hanlon <rickhanlonii@gmail.com>
Co-authored-by: Rick Hanlon <rickhanlonii@fb.com>
Co-authored-by: Lauren Tan <poteto@users.noreply.github.com>
2022-09-14 11:39:06 -07:00
Ricky
0de3ddf56e
Remove Symbol Polyfill (again) (#25144) 2022-08-25 17:01:30 -04:00
Andrew Clark
b6978bc38f
experimental_use(promise) (#25084)
* Internal `act`: Unwrapping resolved promises

This update our internal implementation of `act` to support React's new
behavior for unwrapping promises. Like we did with Scheduler, when 
something suspends, it will yield to the main thread so the microtasks
can run, then continue in a new task.

I need to implement the same behavior in the public version of `act`,
but there are some additional considerations so I'll do that in a
separate commit.

* Move throwException to after work loop resumes

throwException is the function that finds the nearest boundary and
schedules it for a second render pass. We should only call it right 
before we unwind the stack — not if we receive an immediate ping and
render the fiber again.

This was an oversight in 8ef3a7c that I didn't notice because it happens
to mostly work, anyway. What made me notice the mistake is that
throwException also marks the entire render phase as suspended
(RootDidSuspend or RootDidSuspendWithDelay), which is only supposed to
be happen if we show a fallback. One consequence was that, in the 
RootDidSuspendWithDelay case, the entire commit phase was blocked,
because that's the exit status we use to block a bad fallback
from appearing.

* Use expando to check whether promise has resolved

Add a `status` expando to a thrown thenable to track when its value has
resolved.

In a later step, we'll also use `value` and `reason` expandos to track
the resolved value.

This is not part of the official JavaScript spec — think of
it as an extension of the Promise API, or a custom interface that is a
superset of Thenable. However, it's inspired by the terminology used
by `Promise.allSettled`.

The intent is that this will be a public API — Suspense implementations
can set these expandos to allow React to unwrap the value synchronously
without waiting a microtask.

* Scaffolding for `experimental_use` hook

Sets up a new experimental hook behind a feature flag, but does not
implement it yet.

* use(promise)

Adds experimental support to Fiber for unwrapping the value of a promise
inside a component. It is not yet implemented for Server Components, 
but that is planned.

If promise has already resolved, the value can be unwrapped
"immediately" without showing a fallback. The trick we use to implement
this is to yield to the main thread (literally suspending the work
loop), wait for the microtask queue to drain, then check if the promise
resolved in the meantime. If so, we can resume the last attempted fiber
without unwinding the stack. This functionality was implemented in 
previous commits.

Another feature is that the promises do not need to be cached between
attempts. Because we assume idempotent execution of components, React
will track the promises that were used during the previous attempt and
reuse the result. You shouldn't rely on this property, but during
initial render it mostly just works. Updates are trickier, though,
because if you used an uncached promise, we have no way of knowing 
whether the underlying data has changed, so we have to unwrap the
promise every time. It will still work, but it's inefficient and can
lead to unnecessary fallbacks if it happens during a discrete update.

When we implement this for Server Components, this will be less of an
issue because there are no updates in that environment. However, it's
still better for performance to cache data requests, so the same
principles largely apply.

The intention is that this will eventually be the only supported way to
suspend on arbitrary promises. Throwing a promise directly will
be deprecated.
2022-08-25 14:12:07 -04:00
Joseph Savona
9e67e7a315
Scaffolding for useMemoCache hook (#25123)
* Scaffolding for useMemoCache hook
* cleanup leftovers from copy/paste of use() diff

Co-authored-by: Andrew Clark <git@andrewclark.io>
2022-08-23 09:36:02 +01:00
Josh Story
796d31809b
Implement basic stylesheet Resources for react-dom (#25060)
Implement basic support for "Resources". In the context of this commit, the only thing that is currently a Resource are

<link rel="stylesheet" precedence="some-value" ...>

Resources can be rendered anywhere in the react tree, even outside of normal parenting rules, for instance you can render a resource before you have rendered the <html><head> tags for your application. In the stream we reorder this so the browser always receives valid HTML and resources are emitted either in place (normal circumstances) or at the top of the <head> (when you render them above or before the <head> in your react tree)

On the client, resources opt into an entirely different hydration path. Instead of matching the location within the Document these resources are queried for in the entire document. It is an error to have more than one resource with the same href attribute.

The use of precedence here as an opt-in signal for resourcifying the link is in preparation for a more complete Resource implementation which will dedupe resource references (multiple will be valid), hoist to the appropriate container (body, head, or elsewhere), order (according to precedence) and Suspend boundaries that depend on them. More details will come in the coming weeks on this plan.

This feature is gated by an experimental flag and will only be made available in experimental builds until some future time.
2022-08-12 13:27:53 -07:00
Andrew Clark
229c86af07
Revert "Land enableClientRenderFallbackOnTextMismatch" (#24738)
This reverts commit 327e4a1f96.

Turns out we hadn't rolled this out internally yet — I mistook
enableClientRenderFallbackOnHydrationMismatch for
said enableClientRenderFallbackOnTextMismatch. Need to revert
until we finish rolling out the change.
2022-06-16 11:38:37 -04:00
Andrew Clark
327e4a1f96 [Follow-up] Land enableClientRenderFallbackOnTextMismatch
This was meant to land in the previous commit; forgot to stage the
changes when I was rebasing.
2022-06-13 12:01:44 -04:00
Andrew Clark
a8c9cb18b7
Land enableSuspenseLayoutEffectSemantics flag (#24713)
This was released to open source in 18.0 and is already hardcoded to
true in www.
2022-06-13 11:27:40 -04:00
Ricky
62662633d1
Remove enableFlipOffscreenUnhideOrder (#24545) 2022-05-12 12:40:17 -04:00
Ricky
a10a9a6b5b
Add test for hiding children after layout destroy (#24483) 2022-05-03 14:24:23 -04:00
Ricky
99eef9e2df
Hide children of Offscreen after destroy effects (#24446) 2022-05-03 10:16:53 -04:00
Andrew Clark
ce13860281
Remove enablePersistentOffscreenHostContainer flag (#24460)
This was a Fabric-related experiment that we ended up not shipping.
2022-04-28 15:05:41 -04:00
Andrew Clark
0dc4e6663d
Land enableClientRenderFallbackOnHydrationMismatch (#24410)
This flag is already enabled on all relevant surfaces. We can remove it.
2022-04-20 14:09:11 -04:00
Andrew Clark
354772952a
Land enableSelectiveHydration flag (#24406)
This flag is already enabled on all relevant surfaces. We can remove it.
2022-04-20 10:26:25 -04:00
Andrew Clark
392808a1f7
Land enableClientRenderFallbackOnTextMismatch flag (#24405)
This flag is already enabled on all relevant surfaces. We can remove it.
2022-04-20 10:21:36 -04:00
Andrew Clark
1e748b4528
Land enableLazyElements flag (#24407)
This flag is already enabled on all relevant surfaces. We can remove it.
2022-04-20 10:17:52 -04:00
Ricky
4175f05934
Temporarily feature flag numeric fallback for symbols (#24401) 2022-04-19 17:34:49 -04:00
Ricky
a6d53f3468
Revert "Clean up Selective Hydration / Event Replay flag (#24156)" (#24402)
This reverts commit b5cca182ffd5500b83f20f215d0e16d6dbae0efb.
2022-04-19 17:34:30 -04:00
salazarm
6b85823b35
Clean up Selective Hydration / Event Replay flag (#24156)
* clean up selective hydration / replay flag

* dont export return_targetInst
2022-03-24 14:12:43 -04:00
David McCabe
577f2de46c
enableCacheElement flag (#24131)
* enableCacheElement flag

* Update packages/shared/forks/ReactFeatureFlags.testing.js

Co-authored-by: Ricky <rickhanlonii@gmail.com>

* Update packages/shared/forks/ReactFeatureFlags.test-renderer.js

Co-authored-by: Ricky <rickhanlonii@gmail.com>

* Update packages/shared/forks/ReactFeatureFlags.native-oss.js

Co-authored-by: Ricky <rickhanlonii@gmail.com>

* Update packages/shared/ReactFeatureFlags.js

Co-authored-by: Ricky <rickhanlonii@gmail.com>

Co-authored-by: Dave McCabe <davemccabe@fb.com>
Co-authored-by: Ricky <rickhanlonii@gmail.com>
2022-03-20 20:41:02 -07:00
salazarm
ef23a9ee81
Flag for text hydration mismatch (#24107)
* flag for text hydration mismatch

* rm unused import
2022-03-16 10:12:59 -04:00
Sebastian Markbåge
72a933d289
Gate legacy hidden (#24047)
* Gate legacy hidden

* Gate tests

* Remove export from experimental
2022-03-09 11:48:03 -05:00
salazarm
d5f1b067c8
[ServerContext] Flight support for ServerContext (#23244)
* Flight side of server context

* 1 more test

* rm unused function

* flow+prettier

* flow again =)

* duplicate ReactServerContext across packages

* store default value when lazily initializing server context

* .

* better comment

* derp... missing import

* rm optional chaining

* missed feature flag

* React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED ??

* add warning if non ServerContext passed into useServerContext

* pass context in as array of arrays

* make importServerContext nott pollute the global context state

* merge main

* remove useServerContext

* dont rely on object getters in ReactServerContext and disallow JSX

* add symbols to devtools + rename globalServerContextRegistry to just ContextRegistry

* gate test case as experimental

* feedback

* remove unions

* Lint

* fix oopsies (tests/lint/mismatching arguments/signatures

* lint again

* replace-fork

* remove extraneous change

* rebase

* 1 more test

* rm unused function

* flow+prettier

* flow again =)

* duplicate ReactServerContext across packages

* store default value when lazily initializing server context

* .

* better comment

* derp... missing import

* rm optional chaining

* missed feature flag

* React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED ??

* add warning if non ServerContext passed into useServerContext

* pass context in as array of arrays

* make importServerContext nott pollute the global context state

* merge main

* remove useServerContext

* dont rely on object getters in ReactServerContext and disallow JSX

* add symbols to devtools + rename globalServerContextRegistry to just ContextRegistry

* gate test case as experimental

* feedback

* remove unions

* Lint

* fix oopsies (tests/lint/mismatching arguments/signatures

* lint again

* replace-fork

* remove extraneous change

* rebase

* reinline

* rebase

* add back changes lost due to rebase being hard

* emit chunk for provider

* remove case for React provider type

* update type for SomeChunk

* enable flag with experimental

* add missing types

* fix flow type

* missing type

* t: any

* revert extraneous type change

* better type

* better type

* feedback

* change import to type import

* test?

* test?

* remove react-dom

* remove react-native-renderer from react-server-native-relay/package.json

* gate change in FiberNewContext, getComponentNameFromType, use switch statement in FlightServer

* getComponentNameFromTpe: server context type gated and use displayName if available

* fallthrough

* lint....

* POP

* lint
2022-03-08 07:55:32 -05:00
Sebastian Markbåge
6edd55a3ff
Gate unstable_expectedLoadTime on enableCPUSuspense (#24038) 2022-03-08 01:33:52 -05:00
Andrew Clark
a82ef6d40b
Add back skipUnmountedBoundaries flag only for www (#23383)
There are a few internal tests that still need to be updated, so I'm
adding this flag back for www only.

The desired behavior rolled out to 10% public, so we're confident there
are no issues.

The open source behavior remains (skipUnmountedBoundaries = true).
2022-02-28 11:14:30 -05:00
Andrew Clark
a5b22155c8
Warn if renderSubtreeIntoContainer is called (#23355)
We already warn for all the other legacy APIs. Forgot to enable
this one.
2022-02-24 01:42:22 -05:00
Andrew Clark
b3f3da205b
Land warnOnSubscriptionInsideStartTransition flag (#23353)
We're including this in 18. The feature was already enabled — this just
removes the flag.
2022-02-23 18:52:08 -05:00
Andrew Clark
990098f88a
Re-arrange main ReactFeatureFlags module (#23350)
@sebmarkbage and I audited the feature flags file to review the status
of each feature or experiment. Based on that, I've added some more
comments to the main ReactFeatureFlags module and rearranged them
into groups.

I haven't changed the value of any flags, yet. There are a few we're
going to land but I'll do them as separate PRs.
2022-02-23 18:49:16 -05:00
Andrew Clark
419ccc2b19
Land skipUnmountedBoundaries experiment (#23322)
This has been rolled out to 10% of Facebook users for months without
any issues.
2022-02-17 21:43:25 -05:00
Andrew Clark
54f785bc51
Disallow comments as DOM containers for createRoot (#23321)
This is an old feature that we no longer support. `hydrateRoot` already
throws if you pass a comment node; this change makes `createRoot`
throw, too.

Still enabled in the Facebook build until we migrate the callers.
2022-02-17 16:44:22 -05:00
salazarm
3a44621296
Disable avoidThisFallback support in Fizz (#23224)
* disable fizz avoidThisFallback support

* true
2022-02-01 18:22:04 -05:00
Dan Abramov
e489402557
Warn when a callback ref returns a function (#23145) 2022-01-20 15:18:38 +00:00
Luna Ruan
811634762a
add enableTransitionTracing feature flag (#23079)
This PR adds the enableTransitionTracing feature flag
2022-01-10 12:32:40 -08:00
Joey Arhar
24dd07bd26
Add custom element property support behind a flag (#22184)
* custom element props

* custom element events

* use function type for on*

* tests, htmlFor

* className

* fix ReactDOMComponent-test

* started on adding feature flag

* added feature flag to all feature flag files

* everything passes

* tried to fix getPropertyInfo

* used @gate and __experimental__

* remove flag gating for test which already passes

* fix onClick test

* add __EXPERIMENTAL__ to www flags, rename eventProxy

* Add innerText and textContent to reservedProps

* Emit warning when assigning to read only properties in client

* Revert "Emit warning when assigning to read only properties in client"

This reverts commit 1a093e584ce50e2e634aa743e04f9cb8fc2b3f7d.

* Emit warning when assigning to read only properties during hydration

* yarn prettier-all

* Gate hydration warning test on flag

* Fix gating in hydration warning test

* Fix assignment to boolean properties

* Replace _listeners with random suffix matching

* Improve gating for hydration warning test

* Add outerText and outerHTML to server warning properties

* remove nameLower logic

* fix capture event listener test

* Add coverage for changing custom event listeners

* yarn prettier-all

* yarn lint --fix

* replace getCustomElementEventHandlersFromNode with getFiberCurrentPropsFromNode

* Remove previous value when adding event listener

* flow, lint, prettier

* Add dispatchEvent to make sure nothing crashes

* Add state change to reserved attribute tests

* Add missing feature flag test gate

* Reimplement SSR changes in ReactDOMServerFormatConfig

* Test hydration for objects and functions

* add missing test gate

* remove extraneous comment

* Add attribute->property test
2021-12-08 15:11:42 +00:00
salazarm
3f9480f0f5
enable continuous replay flag (#22863) 2021-12-03 19:35:20 -05:00
Dan Abramov
ed00d2c3d8
Remove unused flag (#22854) 2021-12-02 02:25:32 +00:00
salazarm
fdc1d617a4
Flag for client render fallback behavior on hydration mismatch (#22787)
* Add flag for new client-render fallback behavior on hydration mismatch

* gate test

* gate tests too

* fix test gating
2021-11-18 08:16:09 -05:00
Brian Vaughn
51c558aeb6
Rename (some) "scheduling profiler" references to "timeline" (#22690) 2021-11-03 15:10:29 -04:00
Andrew Clark
a0d991fe65
Re-land #22292 (remove uMS from open source build) (#22664)
I had to revert #22292 because there are some internal callers of
useMutableSource that we haven't migrated yet. This removes
useMutableSource from the open source build but keeps it in the
internal one.
2021-10-31 21:39:51 -07:00
salazarm
0ecbbe1422
Sync hydrate discrete events in capture phase and dont replay discrete events (#22448) 2021-10-04 09:54:33 -04:00
salazarm
64e70f82e9
[Fizz] add avoidThisFallback support (#22318) 2021-09-20 15:44:48 -04:00
Dan Abramov
67222f044c
[Experiment] Warn if callback ref returns a function (#22313) 2021-09-15 13:51:39 +01:00
salazarm
a3fde23588
Detect subscriptions wrapped in startTransition (#22271)
* Detect subscriptions wrapped in startTransition
2021-09-08 17:01:09 -04:00
Dan Abramov
2f156eafb8
Adjust consoleManagedByDevToolsDuringStrictMode feature flag (#22253) 2021-09-07 19:51:12 +01:00
Luna Ruan
fc40f02adb
Add consoleManagedByDevToolsDuringStrictMode feature flag in React Reconciler (#22196) 2021-09-01 11:56:52 -07:00
Andrew Clark
19092ac8c3
Re-add old Fabric Offscreen impl behind flag (#22018)
* Re-add old Fabric Offscreen impl behind flag

There's a chance that #21960 will affect layout in a way that we don't
expect, so I'm adding back the old implementation so we can toggle the
feature with a flag.

The flag should read from the ReactNativeFeatureFlags shim so that we
can change it at runtime. I'll do that separately.

* Import dynamic RN flags from external module

Internal feature flags that we wish to control with a GK can now be
imported from an external module, which I've called
"ReactNativeInternalFeatureFlags".

We'll need to add this module to the downstream repo.

We can't yet use this in our tests, because we don't have a test
configuration that runs against the React Native feature flags fork. We
should set up that up the same way we did for www.
2021-08-03 19:30:20 -07:00
Brian Vaughn
4758e4533e
React Native: Export getInspectorDataForInstance API (#21572)
This PR exports a new top-level API, getInspectorDataForInstance, for React Native (both development and production). Although this change adds a new export to the DEV bundle, it only impacts the production bundle for internal builds (not what's published to NPM).
2021-07-26 09:56:59 -04:00
Brian Vaughn
87b67d319f
Enable scheduling profiler flag for react-dom profiling builds (#21867) 2021-07-13 13:41:19 -04:00
Andrew Clark
06f7b4f43a
act should work without mock Scheduler (#21714)
Currently, in a React 18 root, `act` only works if you mock the
Scheduler package. This was because we didn't want to add additional
checks at runtime.

But now that the `act` testing API is dev-only, we can simplify its
implementation.

Now when an update is wrapped with `act`, React will bypass Scheduler
entirely and push its tasks onto a special internal queue. Then, when
the outermost `act` scope exists, we'll flush that queue.

I also removed the "wrong act" warning, because the plan is to move
`act` to an isomorphic entry point, simlar to `startTransition`. That's
not directly related to this PR, but I didn't want to bother
re-implementing that warning only to immediately remove it.

I'll add the isomorphic API in a follow up.

Note that the internal version of `act` that we use in our own tests
still depends on mocking the Scheduler package, because it needs to work
in production. I'm planning to move that implementation to a shared
(internal) module, too.
2021-06-22 14:25:07 -07:00
Dan Abramov
101ea9f55c
Set deletedTreeCleanUpLevel to 3 (#21679) 2021-06-14 20:10:24 +01:00
Sebastian Markbåge
1d3558965f
Disable deferRenderPhaseUpdateToNextBatch by default (#21605)
We're still experimenting with this and it causes a breaking behavior
for setState in componentWillMount/componentWillReceiveProps atm.
2021-06-02 11:28:06 -07:00
Brian Vaughn
63091939bd
OSS feature flag updates (#21597)
Co-authored-by: Dan Abramov <dan.abramov@me.com>
2021-06-01 13:44:10 -04:00
Brian Vaughn
6405efc368
Enabled Profiling feature flags for OSS release (#21565)
* Enabled Profiling feature flags for OSS release

`enableProfilerCommitHooks` and `enableProfilerNestedUpdatePhase`
2021-05-25 17:32:14 -04:00
Brian Vaughn
2bf4805e4b
Update entry point exports (#21488)
The following APIs have been added to the `react` stable entry point:
* `SuspenseList`
* `startTransition`
* `unstable_createMutableSource`
* `unstable_useMutableSource`
* `useDeferredValue`
* `useTransition`

The following APIs have been added or removed from the `react-dom` stable entry point:
* `createRoot`
* `unstable_createPortal` (removed)

The following APIs have been added to the `react-is` stable entry point:
* `SuspenseList`
* `isSuspenseList`

The following feature flags have been changed from experimental to true:
* `enableLazyElements`
* `enableSelectiveHydration`
* `enableSuspenseServerRenderer`
2021-05-12 11:28:14 -04:00
Ricky
9e9dac6505
Add unstable_concurrentUpdatesByDefault (#21227) 2021-04-28 16:09:30 -04:00
Brian Vaughn
fc33f12bde
Remove unstable scheduler/tracing API (#20037) 2021-04-26 19:16:18 -04:00
Ricky
933880b454
Make time-slicing opt-in (#21072)
* Add enableSyncDefaultUpdates feature flag

* Add enableSyncDefaultUpdates implementation

* Fix tests

* Switch feature flag to true by default

* Finish concurrent render whenever for non-sync lanes

* Also return DefaultLane with eventLane

* Gate interruption test

* Add continuout native event test

* Fix tests from rebasing main

* Hardcode lanes, remove added export

* Sync forks
2021-04-09 19:50:09 -04:00
Brian Vaughn
dc108b0f55
Track which fibers scheduled the current render work (#15658)
Tracked Fibers are called "updaters" and are exposed to DevTools via a 'memoizedUpdaters' property on the ReactFiberRoot. The implementation of this feature follows a vaguely similar approach as interaction tracing, but does not require reference counting since there is no subscriptions API.

This change is in support of a new DevTools Profiler feature that shows which Fiber(s) scheduled the selected commit in the Profiler.

All changes have been gated behind a new feature flag, 'enableUpdaterTracking', which is enabled for Profiling builds by default. We also only track updaters when DevTools has been detected, to avoid doing unnecessary work.
2021-04-09 10:34:33 -04:00
Brian Vaughn
7c1ba2b57d
Proposed new Suspense layout effect semantics (#21079)
This commit contains a proposed change to layout effect semantics within Suspense subtrees: If a component mounts within a Suspense boundary and is later hidden (because of something else suspending) React will cleanup that component’s layout effects (including React-managed refs).

This change will hopefully fix existing bugs that occur because of things like reading layout in a hidden tree and will also enable a point at which to e.g. pause videos and hide user-managed portals. After the suspended boundary resolves, React will setup the component’s layout effects again (including React-managed refs).

The scenario described above is not common. The useTransition API should ensure that Suspense does not revert to its fallback state after being mounted.

Note that these changes are primarily written in terms of the (as of yet internal) Offscreen API as we intend to provide similar effects semantics within recently shown/hidden Offscreen trees in the future. (More to follow.)

(Note that all changes in this PR are behind a new feature flag, enableSuspenseLayoutEffectSemantics, which is disabled for now.)
2021-04-06 09:21:02 -04:00
Andrew Clark
a77dd13ede
Delete enableDiscreteEventFlushingChange (#21110)
This flag was meant to avoid flushing discrete updates unnecessarily,
if multiple discrete events were dispatched in response to the same
platform event.

But since we now flush all discrete events at the end of the task, in
a microtask, it no longer has any effect.
2021-03-25 22:05:59 -07:00
Benoit Girard
25bfa287f6
[Experiment] Add feature flag for more aggressive memory clean-up of deleted fiber trees (#21039)
* Add feature flag: enableStrongMemoryCleanup

Add a feature flag that will test doing a recursive clean of an unmount
node. This will disconnect the fiber graph making leaks less severe.

* Detach sibling pointers in old child list

When a fiber is deleted, it's still part of the previous (alternate)
parent fiber's list of children. Because children are a linked list, an
earlier sibling that's still alive will be connected to the deleted
fiber via its alternate:


  live fiber
  --alternate--> previous live fiber
  --sibling--> deleted fiber

We can't disconnect `alternate` on nodes that haven't been deleted
yet, but we can disconnect the `sibling` and `child` pointers.

Will use this feature flag to test the memory impact.

* Combine into single enum flag

I combined `enableStrongMemoryCleanup` and `enableDetachOldChildList`
into a single enum flag. The flag has three possible values. Each level
is a superset of the previous one and performs more aggressive clean up.

We will use this to compare the memory impact of each level.

* Add Flow type to new host config method

* Re-use existing recursive clean up path

We already have a recursive loop that visits every deleted fiber. We
can re-use that one for clean up instead of adding another one.

Co-authored-by: Andrew Clark <git@andrewclark.io>
2021-03-22 21:54:53 -07:00
Andrew Clark
be5a2e231a
Land enableSyncMicrotasks (#20979) 2021-03-19 15:28:41 -07:00
Ricky
860f673a7a
Remove Blocking Mode (again) (#20974)
* Remove Blocking Mode (again)

* Rename batchingmode file and comment
2021-03-10 18:34:35 -05:00
Ricky
e4d4b7074d
Land enableNativeEventPriorityInference (#20955)
* Land enableNativeEventPriorityInference

* Move schedulerPriorityToLanePriority

* Remove obsolete comment
2021-03-09 23:59:02 -05:00
Ricky
73e900b0e7
Land enableDiscreteEventMicroTasks (#20954) 2021-03-08 16:43:44 -05:00
Rick Hanlon
e89d74ee67
Remove decoupleUpdatePriorityFromScheduler 2021-03-08 12:49:57 -07:00
Andrew Clark
258b375a41 Move context comparison to consumer
In the lazy context implementation, not all context changes are
propagated from the provider, so we can't rely on the propagation alone
to mark the consumer as dirty. The consumer needs to compare to the
previous value, like we do for state and context.

I added a `memoizedValue` field to the context dependency type. Then in
the consumer, we iterate over the current dependencies to see if
something changed. We only do this iteration after props and state has
already bailed out, so it's a relatively uncommon path, except at the
root of a changed subtree. Alternatively, we could move these
comparisons into `readContext`, but that's a much hotter path, so I
think this is an appropriate trade off.
2021-03-07 00:37:15 -06:00
Andrew Clark
ee43263572
Revert "Remove blocking mode and blocking root (#20888)" (#20916)
This reverts commit 553440bd15.
2021-03-02 12:51:18 -08:00
Ricky
553440bd15
Remove blocking mode and blocking root (#20888)
* Remove blocking mode and blocking root

* Add back SuspenseList test

* Clean up ReactDOMLegacyRoot

* Remove dupe ConcurrentRoot

* Update comment
2021-02-28 01:14:54 -05:00
Ricky
c581cdd480
Schedule sync updates in microtask (#20872)
* Schedule sync updates in microtask

* Updates from review

* Fix comment
2021-02-25 17:25:25 -05:00
Brian Vaughn
9209c30ff9
Add StrictMode level prop and createRoot unstable_strictModeLevel option (#20849)
* The exported '<React.StrictMode>' tag remains the same and opts legacy subtrees into strict mode level one ('mode == StrictModeL1'). This mode enables DEV-only double rendering, double component lifecycles, string ref warnings, legacy context warnings, etc. The primary purpose of this mode is to help detected render phase side effects. No new behavior. Roots created with experimental 'createRoot' and 'createBlockingRoot' APIs will also (for now) continue to default to strict mode level 1.

In a subsequent commit I will add support for a 'level' attribute on the '<React.StrictMode>' tag (as well as a new option supported by ). This will be the way to opt into strict mode level 2 ('mode == StrictModeL2'). This mode will enable DEV-only double invoking of effects on initial mount. This will simulate future Offscreen API semantics for trees being mounted, then hidden, and then shown again. The primary purpose of this mode is to enable applications to prepare for compatibility with the new Offscreen API (more information to follow shortly).

For now, this commit changes no public facing behavior. The only mechanism for opting into strict mode level 2 is the pre-existing 'enableDoubleInvokingEffects' feature flag (only enabled within Facebook for now).

* Renamed strict mode constants

StrictModeL1 -> StrictLegacyMode and StrictModeL2 -> StrictEffectsMode

* Renamed tests

* Split strict effects mode into two flags

One flag ('enableStrictEffects') enables strict mode level 2. It is similar to 'debugRenderPhaseSideEffectsForStrictMode' which enables srtict mode level 1.

The second flag ('createRootStrictEffectsByDefault') controls the default strict mode level for 'createRoot' trees. For now, all 'createRoot' trees remain level 1 by default. We will experiment with level 2 within Facebook.

This is a prerequisite for adding a configurable option to 'createRoot' that enables choosing a different StrictMode level than the default.

* Add StrictMode 'unstable_level' prop and createRoot 'unstable_strictModeLevel' option

New StrictMode 'unstable_level' prop allows specifying which level of strict mode to use. If no level attribute is specified, StrictLegacyMode will be used to maintain backwards compatibility. Otherwise the following is true:
* Level 0 does nothing
* Level 1 selects StrictLegacyMode
* Level 2 selects StrictEffectsMode (which includes StrictLegacyMode)

Levels can be increased with nesting (0 -> 1 -> 2) but not decreased.

This commit also adds a new 'unstable_strictModeLevel' option to the createRoot and createBatchedRoot APIs. This option can be used to override default behavior to increase or decrease the StrictMode level of the root.

A subsequent commit will add additional DEV warnings:
* If a nested StrictMode tag attempts to explicitly decrease the level
* If a level attribute changes in an update
2021-02-24 16:14:14 -05:00
Ricky
4d28eca97e
Land enableNonInterruptingNormalPri (#20859) 2021-02-22 12:56:54 -05:00
Andrew Clark
3b870b1e09
Lane enableTransitionEntanglement flag (#20775) 2021-02-10 00:25:39 -08:00
Andrew Clark
d1845ad0ff
Default updates should not interrupt transitions (#20771)
The only difference between default updates and transition updates is
that default updates do not support suspended refreshes — they will
instantly display a fallback.

Co-authored-by: Rick Hanlon <rickhanlonii@gmail.com>
2021-02-10 00:00:24 -08:00
Dan Abramov
97fce318a6
Experiment: Infer the current event priority from the native event (#20748)
* Add the feature flag

* Add a host config method

* Wire it up to the work loop

* Export constants for third-party renderers

* Document for third-party renderers
2021-02-09 18:32:20 +00:00
Dan Abramov
4ecf11977c
Remove the Fundamental internals (#20745) 2021-02-05 20:36:55 +00:00
Ricky
e51bd6c1fa
Queue discrete events in microtask (#20669)
* Queue discrete events in microtask

* Use callback priority to determine cancellation

* Add queueMicrotask to react-reconciler README

* Fix invatiant conditon for InputDiscrete

* Switch invariant null check

* Convert invariant to warning

* Remove warning from codes.json
2021-01-27 18:24:58 -05:00
Andrew Clark
d13f5b9538
Experiment: Unsuspend all lanes on update (#20660)
Adds a feature flag to tweak the internal heuristic used to "unsuspend"
lanes when a new update comes in.

A lane is "suspended" if we couldn't finish rendering it because it was
missing data, and we chose not to commit the fallback. (In this context,
"suspended" does not include updates that finished with a fallback.)

When we receive new data in the form of an update, we need to retry
rendering the suspended lanes, since the new data may have unblocked the
previously suspended work. For example, the new update could navigate
back to an already loaded route.

It's impractical to retry every combination of suspended lanes, so we
need some heuristic that decides which lanes to retry and in
which order.

The existing heuristic roughly approximates the old Expiration Times
model. It unsuspends all lower priority lanes, but leaves higher
priority lanes suspended.

Then when we start rendering, we choose the lanes that have the highest
LanePriority and render those -- and then we add to that all the lanes
that are highher priority.

If this sounds terribly confusing, it's because it barely makes sense.
(It made more sense in the Expiration Times world, I promise, but it
was still confusing.) I don't think it's worth me trying to explain the
old behavior too much because the point here is that we can replace it
with something simpler.

The new heurstic is to unsuspend all suspended lanes whenever there's
an update.

This is effectively what we already do except in a few very specific
edge cases, ever since we removed the delayed suspense feature from
everything that's not a refresh transition.

We can optimize this in the future to only unsuspend lanes that are
either 1) in the `lanes` or `subtreeLanes` of the node that was updated,
or 2) in the `lanes` of the return path of the node that was updated.
This would exclude lanes that are only located in unrelated sibling
trees. But, this optimization wouldn't be useful currently because we
assign the same transition lane to all transitions. It will become
relevant again once we start assigning arbitrary lanes to transitions
-- but that in turn requires us to implement entanglement of overlapping
transitions, one of our planned projects.

So to sum up: the goal here is to remove the weird edge cases and switch
to a simpler model, on top of which we can make more substantial
improvements.

I put it behind a flag so I can run an A/B test and confirm it doesn't
cause a regression.
2021-01-26 12:23:34 -08:00
Brian Vaughn
895ae67fd3
Improve error boundary handling for unmounted subtrees (#20645)
A passive effect's cleanup function may throw after an unmount. Prior to this commit, such an error would be ignored. (React would not notify any error boundaries.)

After this commit, React will skip any unmounted boundaries and look for a still-mounted boundary. If one is found, it will call getDerivedStateFromError and/or componentDidCatch (depending on the type of boundary). Unmounted boundaries will be ignored, but as they have been unmounted– this seems appropriate.
2021-01-25 08:54:20 -05:00
Ricky
5687864eb7
Add back disableSchedulerTimeoutInWorkLoop flag (#20482)
* Add back enableSchedulerTimeoutInWorkLoop flag

* Nvm, keep it as disableSchedulerTimeoutInWorkLoop
2020-12-17 17:17:23 -05:00
Dan Abramov
e23673b511
[Flight] Add getCacheForType() to the dispatcher (#20315)
* Remove react/unstable_cache

We're probably going to make it available via the dispatcher. Let's remove this for now.

* Add readContext() to the dispatcher

On the server, it will be per-request.

On the client, there will be some way to shadow it.

For now, I provide it on the server, and throw on the client.

* Use readContext() from react-fetch

This makes it work on the server (but not on the client until we implement it there.)

Updated the test to use Server Components. Now it passes.

* Fixture: Add fetch from a Server Component

* readCache -> getCacheForType<T>

* Add React.unstable_getCacheForType

* Add a feature flag

* Fix Flow

* Add react-suspense-test-utils and port tests

* Remove extra Map lookup

* Unroll async/await because build system

* Add some error coverage and retry

* Add unstable_getCacheForType to Flight entry
2020-12-03 03:44:56 +00:00
Philipp Spiess
555eeae33d
Add disableNativeComponentFrames flag (#20364)
## Summary

We're experiencing some issues internally where the component stack is
getting into our way of fixing them as it causes the page to become
unresponsive. This adds a flag so that we can disable this feature as a
temporary workaround.

More internal context: https://fburl.com/go9yoklm

## Test Plan

I tried to default this flag to `__VARIANT__` but the variant tests
(`yarn test-www --variant`) started to fail across the board since a lot
of tests depend on the component tree, things like this:

https://user-images.githubusercontent.com/458591/100771192-6a1e1c00-33fe-11eb-9ab0-8ff46ba378a2.png

So, it seems to work :-)

Given that it's unhandy to update the hundreds of tests that are failing
I decided to hard code this to `false` like we already do for some other
options.
2020-12-02 16:25:55 +01:00
Brian Vaughn
9403c3b536
Add Profiler callback when nested updates are scheduled (#20211)
This callback accepts the no parameters (except for the current interactions). Users of this hook can inspect the call stack to access and log the source location of the component.
2020-11-12 09:31:27 -05:00
Brian Vaughn
393c452e39
Add "nested-update" phase to Profiler API (#20163)
Background:
State updates that are scheduled in a layout effect (useLayoutEffect or componentDidMount / componentDidUpdate) get processed synchronously by React before it yields to the browser to paint. This is done so that components can adjust their layout (e.g. position and size a tooltip) without any visible shifting being seen by users. This type of update is often called a "nested update" or a "cascading update".

Because they delay paint, nested updates are considered expensive and should be avoided when possible. For example, effects that do not impact layout (e.g. adding event handlers, logging impressions) can be safely deferred to the passive effect phase by using useEffect instead.

This PR updates the Profiler API to explicitly flag nested updates so they can be monitored for and avoided when possible.

Implementation:
I considered a few approaches for this.

Add a new callback (e.g. onNestedUpdateScheduled) to the Profiler that gets called when a nested updates gets scheduled.
Add an additional boolean parameter to the end of existing callbacks (e.g. wasNestedUpdate).
Update the phase param to add an additional variant: "mount", "update", or "nested-update" (new).
I think the third option makes for the best API so that's what I've implemented in this PR.

Because the Profiler API is stable, this change will need to remain behind a feature flag until v18. I've turned the feature flag on for Facebook builds though after confirming that Web Speed does not currently make use of the phase parameter.

Quirks:
One quirk about the implementation I've chosen is that errors thrown during the layout phase are also reported as nested updates. I believe this is appropriate since these errors get processed synchronously and block paint. Errors thrown during render or from within passive effects are not affected by this change.
2020-11-10 09:40:30 -05:00
Brian Vaughn
7a73d6a0f9
(Temporarily) revert unmounting error boundaries changes (#20147)
This reverts commits bcca5a6ca7 and ffb749c95e, although neither revert cleanly since methods have been moved between the work-loop and commit-work files. This commit is a mostly manual effort of undoing the changes.
2020-11-09 10:14:24 -05:00
Sebastian Markbåge
56e9feead0
Remove Blocks (#20138)
* Remove Blocks

* Remove Flight Server Runtime

There's no need for this now that the JSResource is part of the bundler
protocol. Might need something for Webpack plugin specifically later.

* Devtools
2020-10-30 23:03:45 -07:00
Andrew Clark
25b18d31c8
Traverse commit phase effects iteratively (#20094)
* Move traversal logic to ReactFiberCommitWork

The current traversal logic is spread between ReactFiberWorkLoop and
ReactFiberCommitWork, and it's a bit awkward, especially when
refactoring. Idk the ideal module structure, so for now I'd rather keep
it all in one file.

* Traverse commit phase effects iteratively

We suspect that using the JS stack to traverse through the tree in the
commit phase is slower than traversing iteratively.

I've kept the recursive implementation behind a flag, both so we have
the option to run an experiment comparing the two, and so we can revert
it easily later if needed.
2020-10-27 12:02:19 -07:00
Brian Vaughn
c59c3dfe55
useRef: Warn about reading or writing mutable values during render (#18545)
Reading or writing a ref value during render is only safe if you are implementing the lazy initialization pattern.

Other types of reading are unsafe as the ref is a mutable source.

Other types of writing are unsafe as they are effectively side effects.

This change also refactors useTransition to no longer use a ref hook, but instead manage its own (stable) hook state.
2020-10-19 16:05:00 -04:00
Dan Abramov
993ca533b4
Enable eager listeners statically (#19983) 2020-10-08 19:32:28 +01:00
Andrew Clark
ba82eea383
Remove disableSchedulerTimeoutInWorkLoop flag (#19902)
We found and mitigated the root cause of the regression that led us to
temporarily revert this change. So now I'm un-reverting it.
2020-09-28 10:19:14 -07:00
Luna Ruan
c63741fb3d
offscreen double invoke effects (#19523)
This PR double invokes effects in __DEV__ mode.

We are thinking about unmounting layout and/or passive effects for a hidden tree. To understand potential issues with this, we want to double invoke effects. This PR changes the behavior in DEV when an effect runs from create() to create() -> destroy() -> create(). The effect cleanup function will still be called before the effect runs in both dev and prod. (Note: This change is purely for research for now as it is likely to break real code.)

**Note: The change is fully behind a flag and does not affect any of the code on npm.**
2020-09-24 13:42:17 -07:00
Dan Abramov
6fddca27e7
Remove passive intervention flag (#19849) 2020-09-17 15:37:12 +01:00
Ricky
36df483af4
Add feature flag to disable scheduler timeout in work loop (#19771) 2020-09-04 10:58:17 -04:00
Dan Abramov
bcc0aa4633
Revert "Revert "Remove onScroll bubbling flag (#19535)" (#19655)" (#19761)
This reverts commit 64ddef44c6.
2020-09-03 17:06:20 +01:00
Dan Abramov
b754caaaf2
Enable eager listeners in open source (#19716)
* Enable eager listeners in open source

* Fix tests

* Enable in all places
2020-08-28 12:23:28 +01:00
Dan Abramov
848bb2426e
Attach Listeners Eagerly to Roots and Portal Containers (#19659)
* Failing test for #19608

* Attach Listeners Eagerly to Roots and Portal Containers

* Forbid createEventHandle with custom events

We can't support this without adding more complexity. It's not clear that this is even desirable, as none of our existing use cases need custom events. This API primarily exists as a deprecation strategy for Flare, so I don't think it is important to expand its support beyond what Flare replacement code currently needs. We can later revisit it with a better understanding of the eager/lazy tradeoff but for now let's remove the inconsistency.

* Reduce risk by changing condition only under the flag

Co-authored-by: koba04 <koba0004@gmail.com>
2020-08-24 16:50:20 +01:00
Dan Abramov
64ddef44c6
Revert "Remove onScroll bubbling flag (#19535)" (#19655)
This reverts commit e9721e14e4.
2020-08-19 20:54:54 +01:00
Dan Abramov
dd651df05e
Keep onTouchStart, onTouchMove, and onWheel passive (#19654)
* Keep onTouchStart, onTouchMove, and onWheel passive

* Put it behind a feature flag on WWW
2020-08-19 18:42:33 +01:00
Brian Vaughn
bcca5a6ca7
Always skip unmounted/unmounting error boundaries (#19627)
The behavior of error boundaries for passive effects that throw during cleanup was recently changed so that React ignores boundaries which are also unmounting in favor of still-mounted boundaries. This commit implements that same behavior for layout effects (useLayoutEffect, componentWillUnmount, and ref-detachment).

The new, skip-unmounting-boundaries behavior is behind a feature flag (`skipUnmountedBoundaries`).
2020-08-17 15:01:06 -04:00
Brian Vaughn
9b35dd2fcc
Permanently removed component stacks from scheduling profiler data (#19615)
These stacks improve the profiler data but they're expensive to generate and generating them can also cause runtime errors in larger applications (although an exact repro has been hard to nail down). Removing them for now. We can revisit adding them after this profiler has been integrated into the DevTools extension and we can generate them lazily.
2020-08-14 15:21:13 -04:00
Dominic Gannaway
f77c7b9d76
Re-add discrete flushing timeStamp heuristic (behind flag) (#19540) 2020-08-06 13:21:05 +01:00
Dan Abramov
e9721e14e4
Remove onScroll bubbling flag (#19535) 2020-08-05 16:07:58 +01:00
Dominic Gannaway
b61174fb7b
Remove the deprecated React Flare event system (#19520) 2020-08-05 15:13:29 +01:00
Dan Abramov
3d0895557a
Disable onScroll bubbling statically except for WWW (#19503) 2020-07-31 15:09:24 +01:00
Dan Abramov
332eceface
Revert "Statically enable enableFilterEmptyStringAttributesDOM (#19502)" (#19504)
This reverts commit 815ee89bf5.
2020-07-31 15:01:27 +01:00
Dan Abramov
815ee89bf5
Statically enable enableFilterEmptyStringAttributesDOM (#19502) 2020-07-31 14:57:57 +01:00
Dan Abramov
06d104e8ec
Don't emulate bubbling of the scroll event (#19464)
* Don't emulate bubbling of the scroll event

* Put behind a flag
2020-07-27 17:33:54 +01:00
Brian Vaughn
51267c4ac9
Sync scheduling profiler marks and debug tracing to new reconciler fork (#19375, #19376, #19396)
* Make enableSchedulingProfiler flag static

* Copied debug tracing and scheduler profiling to .new fork and updated feature flags

* Move profiler component stacks behind a feature flag
2020-07-17 11:24:26 -04:00
Dan Abramov
aec934af7f
Remove form event delegation flag (#19395) 2020-07-17 14:19:39 +01:00
Dominic Gannaway
392277f0ab
Revert "Scheduling profiler updates (#19334)" (#19366)
This reverts commit 6d7555b014.
2020-07-15 12:36:40 +01:00
Brian Vaughn
6d7555b014
Scheduling profiler updates (#19334)
* Make enableSchedulingProfiler static for profiling+experimental builds

* Copied debug tracing and scheduler profiling to .new fork

* Updated test @gate conditions
2020-07-13 22:20:53 -04:00
Dan Abramov
26472c8897
Bubble onSubmit/onReset behind a feature flag (#19333) 2020-07-13 17:17:28 +01:00
E-Liang Tan
40cddfeeb1
Add user timing marks for scheduling profiler tool (#19223)
High level breakdown of this commit:

* Add a enableSchedulingProfiling feature flag.
* Add functions that call User Timing APIs to a new SchedulingProfiler file. The file follows DebugTracing's structure.
* Add user timing marks to places where DebugTracing logs.
* Add user timing marks to most other places where @bvaughn's original draft DebugTracing branch marks.
* Tests added
* More context (and discussions with @bvaughn) available at our internal PR MLH-Fellowship#11 and issue MLH-Fellowship#5.

Similar to DebugTracing, we've only added scheduling profiling calls to the old reconciler fork.

Co-authored-by: Kartik Choudhary <kartik.c918@gmail.com>
Co-authored-by: Kartik Choudhary <kartikc.918@gmail.com>
Co-authored-by: Brian Vaughn <brian.david.vaughn@gmail.com>
2020-07-08 10:36:02 -04:00
Ricky
91a2e8173f
Decouple update priority tracking from Scheduler package (#19121)
* Initial currentLanePriority implementation

* Minor updates from review

* Fix typos and enable flag

* Fix feature flags and lint

* Fix simple event tests by switching to withSuspenseConfig

* Don't lower the priority of setPending in startTransition below InputContinuous

* Move currentUpdateLanePriority in commit root into the first effect block

* Refactor requestUpdateLane to log for priority mismatches

Also verifies that the update lane priority matches the scheduler lane priority before using it

* Fix four tests by adding ReactDOM.unstable_runWithPriority

* Fix partial hydration when using update lane priority

* Fix partial hydration when using update lane priority

* Rename feature flag and only log for now

* Move unstable_runWithPriority to ReactFiberReconciler

* Add unstable_runWithPriority to ReactNoopPersistent too

* Bug fixes and performance improvements

* Initial currentLanePriority implementation

* Minor updates from review

* Fix typos and enable flag

* Remove higherLanePriority from ReactDOMEventReplaying.js

* Change warning implementation and startTransition update lane priority

* Inject reconciler functions to avoid importing src/

* Fix feature flags and lint

* Fix simple event tests by switching to withSuspenseConfig

* Don't lower the priority of setPending in startTransition below InputContinuous

* Move currentUpdateLanePriority in commit root into the first effect block

* Refactor requestUpdateLane to log for priority mismatches

Also verifies that the update lane priority matches the scheduler lane priority before using it

* Fix four tests by adding ReactDOM.unstable_runWithPriority

* Fix partial hydration when using update lane priority

* Fix partial hydration when using update lane priority

* Rename feature flag and only log for now

* Move unstable_runWithPriority to ReactFiberReconciler

* Bug fixes and performance improvements

* Remove higherLanePriority from ReactDOMEventReplaying.js

* Change warning implementation and startTransition update lane priority

* Inject reconciler functions to avoid importing src/

* Fixes from bad rebase
2020-07-06 18:53:42 -04:00
Dan Abramov
9fba65efa5
Enable modern event system and delete dead code (#19230) 2020-07-01 17:43:34 +01:00
Ricky
30b47103d4
Fix spelling errors and typos (#19138) 2020-06-15 19:59:44 -04:00
Andrew Clark
8f05f2bd6d
Land Lanes implementation in old fork (#19108)
* Add autofix to cross-fork lint rule

* replace-fork: Replaces old fork contents with new

For each file in the new fork, copies the contents into the
corresponding file of the old fork, replacing what was already there.

In contrast to merge-fork, which performs a three-way merge.

* Replace old fork contents with new fork

First I ran  `yarn replace-fork`.

Then I ran `yarn lint` with autofix enabled. There's currently no way to
do that from the command line (we should fix that), so I had to edit the
lint script file.

* Manual fix-ups

Removes dead branches, removes prefixes from internal fields.  Stuff
like that.

* Fix DevTools tests

DevTools tests only run against the old fork, which is why I didn't
catch these earlier.

There is one test that is still failing. I'm fairly certain it's related
to the layout of the Suspense fiber: we no longer conditionally wrap the
primary children. They are always wrapped in an extra fiber.

Since this has been running in www for weeks without major issues, I'll
defer fixing the remaining test to a follow up.
2020-06-11 20:05:15 -07:00
Sebastian Markbåge
7f28234f84
Enable component stacks everywhere except RN (#19120)
This would still affect test renderer and isomorphic in RN.
2020-06-11 19:13:13 -07:00
Sebastian Markbåge
518ce9c25f
Add Lazy Elements Behind a Flag (#19033)
We really needed this for Flight before as well but we got away with it
because Blocks were lazy but with the removal of Blocks, we'll need this
to ensure that we can lazily stream in part of the content.

Luckily LazyComponent isn't really just a Component. It's just a generic
type that can resolve into anything kind of like a Promise.

So we can use that to resolve elements just like we can components.

This allows keys and props to become lazy as well.

To accomplish this, we suspend during reconciliation. This causes us to
not be able to render siblings because we don't know if the keys will
reconcile. For initial render we could probably special case this and
just render a lazy component fiber.

Throwing in reconciliation didn't work correctly with direct nested
siblings of a Suspense boundary before but it does now so it depends
on new reconciler.
2020-05-28 14:16:35 -07:00
Sebastian Markbåge
4985bb0a80
Rename 17 to 18 in warnings (#19031)
We're not really supposed to refer to future versions by numbers.

These will all slip so these numbers don't make sense anymore.
2020-05-28 10:25:39 -07:00
Brian Vaughn
86b4070ddb
Cleaned up passive effects experimental flags (#19021) 2020-05-28 08:32:37 -07:00
Andrew Clark
64f50c667a
Remove disableHiddenPropDeprioritization flag (#18964)
This is rolled out to 100% public, so we can remove it.
2020-05-20 15:29:34 -07:00
Andrew Clark
b4a1a4980c
Disable <div hidden /> API in old fork, too (#18917)
The motivation for doing this is to make it impossible for additional
uses of pre-rendering to sneak into www without going through the
LegacyHidden abstraction. Since this feature was already disabled in
the new fork, this brings the two closer to parity.

The LegacyHidden abstraction itself still needs to opt into
pre-rendering somehow, so rather than totally disabling the feature, I
updated the `hidden` prop check to be obnoxiously specific. Before, you
could set it to any truthy value; now, you must set it to the string
"unstable-do-not-use-legacy-hidden".

The node will still be hidden in the DOM, since any truthy value will
cause the browser to apply a style of `display: none`.

I will have to update the LegacyHidden component in www to use the
obnoxious string prop. This doesn't block merge, though, since the
behavior is gated by a dynamic flag. I will update the component before
I enable the flag.
2020-05-13 20:01:10 -07:00
Dominic Gannaway
80c4dea0d1
Modern Event System: Add scaffolding for createEventHandle (#18898) 2020-05-12 19:01:12 +01:00
Andrew Clark
8b9c4d1688
Expose LegacyHidden type and disable <div hidden /> API in new fork (#18891)
* Expose LegacyHidden type

I will use this internally at Facebook to migrate away from
<div hidden />. The end goal is to migrate to the Offscreen type, but
that has different semantics. This is an incremental step.

* Disable <div hidden /> API in new fork

Migrates to the unstable_LegacyHidden type instead. The old fork does
not support the new component type, so I updated the tests to use an
indirection that picks the correct API. I will remove this once the
LegacyHidden (and/or Offscreen) type has landed in both implementations.

* Add gated warning for `<div hidden />` API

Only exists so we can detect callers in www and migrate them to the new
API. Should not visible to anyone outside React Core team.
2020-05-11 20:02:08 -07:00
Andrew Clark
47ebc90b08
Put render phase update change behind a flag (#18850)
In the new reconciler, I made a change to how render phase updates
work. (By render phase updates, I mean when a component updates
another component during its render phase. Or when a class component
updates itself during the render phase. It does not include when
a hook updates its own component during the render phase. Those have
their own semantics. So really I mean anything triggers the "`setState`
in render" warning.)

The old behavior is to give the update the same "thread" (expiration
time) as whatever is currently rendering. So if you call `setState` on a
component that happens later in the same render, it will flush during
that render. Ideally, we want to remove the special case and treat them
as if they came from an interleaved event.

Regardless, this pattern is not officially supported. This behavior is
only a fallback. The flag only exists until we can roll out the
`setState` warnning, since existing code might accidentally rely on the
current behavior.
2020-05-06 19:19:14 -07:00
Dan Abramov
3e13d70984
[RN] Remove debugging invariant (#18813) 2020-05-04 15:48:35 +01:00
Dominic Gannaway
ff431b7fc4
Remove ReactDOM.useEvent and associated types+tests (#18689) 2020-04-21 16:40:44 +01:00
Brian Vaughn
22dc2e42bd
Add experimental DebugTracing logger for internal use (#18531) 2020-04-15 19:10:15 -07:00
Andrew Clark
b928fc030a
Delete flushSuspenseFallbacksInTests flag (#18596)
* Move renderer `act` to work loop

* Delete `flushSuspenseFallbacksInTests`

This was meant to be a temporary hack to unblock the `act` work, but it
quickly spread throughout our tests.

What it's meant to do is force fallbacks to flush inside `act` even in
Concurrent Mode. It does this by wrapping the `setTimeout` call in a
check to see if it's in an `act` context. If so, it skips the delay and
immediately commits the fallback.

Really this is only meant for our internal React tests that need to
incrementally render. Nobody outside our team (and Relay) needs to do
that, yet. Even if/when we do support that, it may or may not be with
the same `flushAndYield` pattern we use internally.

However, even for our internal purposes, the behavior isn't right
because a really common reason we flush work incrementally is to make
assertions on the "suspended" state, before the fallback has committed.
There's no way to do that from inside `act` with the behavior of this
flag, because it causes the fallback to immediately commit. This has led
us to *not* use `act` in a lot of our tests, or to write code that
doesn't match what would actually happen in a real environment.

What we really want is for the fallbacks to be flushed at the *end` of
the `act` scope. Not within it.

This only affects the noop and test renderer versions of `act`, which
are implemented inside the reconciler. Whereas `ReactTestUtils.act` is
implemented in "userspace" for backwards compatibility. This is fine
because we didn't have any DOM Suspense tests that relied on this flag;
they all use test renderer or noop.

In the future, we'll probably want to move always use the reconciler
implementation of `act`. It will not affect the prod bundle, because we
currently only plan to support `act` in dev. Though we still haven't
completely figured that out. However, regardless of whether we support a
production `act` for users, we'll still need to write internal React
tests in production mode. For that use case, we'll likely add our own
internal version of `act` that assumes a mock Scheduler and might rely
on hacks that don't 100% align up with the public one.
2020-04-13 20:02:18 -07:00
Sebastian Markbåge
98d410f500
Build Component Stacks from Native Stack Frames (#18561)
* Implement component stack extraction hack

* Normalize errors in tests

This drops the requirement to include owner to pass the test.

* Special case tests

* Add destructuring to force toObject which throws before the side-effects

This ensures that we don't double call yieldValue or advanceTime in tests.

Ideally we could use empty destructuring but ES lint doesn't like it.

* Cache the result in DEV

In DEV it's somewhat likely that we'll see many logs that add component
stacks. This could be slow so we cache the results of previous components.

* Fixture

* Add Reflect to lint

* Log if out of range.

* Fix special case when the function call throws in V8

In V8 we need to ignore the first line. Normally we would never get there
because the stacks would differ before that, but the stacks are the same if
we end up throwing at the same place as the control.
2020-04-10 13:32:12 -07:00
Brian Vaughn
dc49ea108c
Filter certain DOM attributes (e.g. src) if value is empty string (#18513)
* Filter certain DOM attributes (e.g. src, href) if their values are empty strings

This prevents e.g. <img src=""> from making an unnecessar HTTP request for certain browsers.

* Expanded warning recommendation

* Improved error message

* Further refined error message
2020-04-07 09:52:36 -07:00
Sebastian Markbåge
4169420198
Refactor Component Stack Traces (#18495)
* Add feature flag

* Split stack from current fiber

You can get stack from any fiber, not just current.

* Refactor description of component frames

These should use fiber tags for switching. This also puts the relevant code
behind DEV flags.

* We no longer expose StrictMode in component stacks

They're not super useful and will go away later anyway.

* Update tests

Context is no longer part of SSR stacks. This was already the case on the
client.

forwardRef no longer is wrapped on the stack. It's still in getComponentName
but it's probably just noise in stacks. Eventually we'll remove the wrapper
so it'll go away anyway. If we use native stack frames they won't have this
extra wrapper.

It also doesn't pick up displayName from the outer wrapper. We could maybe
transfer it but this will also be fixed by removing the wrapper.

* Forward displayName onto the inner function for forwardRef and memo in DEV

This allows them to show up in stack traces.

I'm not doing this for lazy because lazy is supposed to be called on the
consuming side so you shouldn't assign it a name on that end. Especially
not one that mutates the inner.

* Use multiple instances of the fake component

We mutate the inner component for its name so we need multiple copies.
2020-04-06 15:43:39 -07:00
Dan Abramov
31734540dc
Remove a flag for style collision warning (#18462) 2020-04-02 11:55:17 +01:00
Brian Vaughn
4de3a60325
Remove disableMapsAsChildren flag (#18445)
Change warning to say the case is unsupported (not "will be deprecated")
2020-03-31 11:00:51 -07:00
Dan Abramov
bf30e370a5
Remove User Timings (#18417) 2020-03-31 00:29:53 +01:00
Dominic Gannaway
8311cb5d24
Modern Event System: refactor legacy FB support logic (#18336) 2020-03-19 13:22:36 +00:00