948 Commits

Author SHA1 Message Date
Dominic Gannaway b2bac7311a Remove React Flare Keyboard responder (#19222) 2020-07-01 15:43:16 +01:00
Dan Abramov 8bff8987e5 Don't bailout after Suspending in Legacy Mode (#19216)
* Add a failing test for legacy Suspense blocking context updates in memo

* Add more test case coverage for variations of #17356

* Don't bailout after Suspending in Legacy Mode

Co-authored-by: Tharuka Devendra <tsdevendra1@gmail.com>
2020-06-30 22:06:46 +01:00
Shailendra Gupta f4097c1aef Added warning to <Context.Provider> in case no value prop is provided (#19054)
* added warning to context.provider in case no value prop

* update message

* updated message and pass undefined
2020-06-30 19:50:55 +01:00
Dan Abramov 47ff31a77a Revert "Add regression test for #18497 (#18538)" (#19215)
This reverts commit e9c1445ba0.
2020-06-30 13:38:31 +01:00
jddxf fa32cf299f Add regression tests where sync render causes later concurrent render to expire soon (#18608)
* Add a failing test for #17911

* Add more test cases where sync render causes later concurrent render to expire soon
2020-06-30 12:42:59 +01:00
Sophie Alpert e9c1445ba0 Add regression test for #18497 (#18538) 2020-06-30 12:09:05 +01:00
Chen Gang ffe516f3bf use NoTimestamp instead of -1 (#19182) 2020-06-23 16:28:24 -04:00
Brian Vaughn 1425fcbb86 Re-enabled DebugTracing feature for old reconciler fork (#19161)
* Re-enabled DebugTracing feature for old reconciler fork

It was temporarily removed by @sebmarkbage via PR #18697. Newly re-added tracing is simplified, since the lane(s) data type does not require the (lossy) conversion between priority and expiration time values.

@sebmarkbage mentioned that he removed this because it might get in the way of his planned discrete/sync refactor. I'm not sure if that concern still applies, but just in case- I have only re-added it to the old reconciler fork for now.

* Force Code Sandbox CI to re-run
2020-06-23 12:16:23 -04:00
Andrew Clark 6ba25b96df Bugfix: Legacy Mode + DevTools "force fallback" (#19164)
DevTools has a feature to force a Suspense boundary to show a fallback.
This feature causes us to skip the first render pass (where we render
the primary children) and go straight to rendering the fallback.

There's a Legacy Mode-only codepath that failed to take this scenario
into account, instead assuming that whenever a fallback is being
rendered, it was preceded by an attempt to render the primary children.

SuspenseList can also cause us to skip the first pass, but the relevant
branch is Legacy Mode-only, and SuspenseList is not supported in
Legacy Mode.

Fixes a test that I had temporarily disabled when upstreaming the Lanes
implementation in #19108.
2020-06-19 11:06:42 -07:00
Luna Ruan d1d9054e09 Revert "Re-enabled DebugTracing feature for old reconciler fork (#19142)" (#19159)
This reverts commit cc7c1aece4.
2020-06-18 18:18:56 -07:00
Brian Vaughn cc7c1aece4 Re-enabled DebugTracing feature for old reconciler fork (#19142)
It was temporarily removed by @sebmarkbage via PR #18697. Newly re-added tracing is simplified, since the lane(s) data type does not require the (lossy) conversion between priority and expiration time values.

@sebmarkbage mentioned that he removed this because it might get in the way of his planned discrete/sync refactor. I'm not sure if that concern still applies, but just in case- I have only re-added it to the old reconciler fork for now.
2020-06-16 15:16:15 -04:00
Ricky 30b47103d4 Fix spelling errors and typos (#19138) 2020-06-15 19:59:44 -04:00
Andrew Clark 103ed08c46 Remove shouldDeprioritizeSubtree from host config (#19124)
No longer being used.
2020-06-12 12:57:20 -07: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
Andrew Clark 4c7036e807 Bugfix: Infinite loop in beforeblur event (#19053)
* Failing test: Infinite loop in beforeblur event

If the focused node is hidden by a Suspense boundary, we fire the
beforeblur event. Our check for whether a tree is being hidden isn't
specific enough. It should only fire when the tree is initially hidden,
but it's being fired for updates, too.

* Only fire beforeblur on visible -> hidden

Should only beforeblur fire if the node was previously visible. Not
during updates to an already hidden tree.

To optimize this, we should use a dedicated effect tag and mark it in
the render phase. I've left this for a follow-up, though. Maybe can
revisit after the planned refactor of the commit phase.

* Move logic to commit phase

isFiberSuspenseAndTimedOut is used elsewhere, so I inlined the commit
logic into the commit phase itself.
2020-06-01 09:01:21 -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 18de3b6e7c Bug: Spawning hydration in response to Idle update (#19011)
* Bug: Spawning hydration in response to Idle update

Adds a test that fails in the new fork.

* Fix typos related to Idle priority

These are just silly mistakes that weren't caught by any of our tests.

There's a lot of duplication in the Lanes module right now. It's also
not super stable as we continue to refine our heuristics. Hopefully the
final state is simpler and less prone to these types of mistakes.
2020-05-26 18:53:50 -07:00
Andrew Clark 03e6b8ba2f Make LegacyHidden match semantics of old fork (#18998)
Facebook currently relies on being able to hydrate hidden HTML. So
skipping those trees is a regression.

We don't have a proper solution for this in the new API yet. So I'm
reverting it to match the old behavior.

Now the server renderer will treat LegacyHidden the same as a fragment,
with no other special behavior. We can only get away with this because
we assume that every instance of LegacyHidden is accompanied by a host
component wrapper. In the hidden mode, the host component is given a
`hidden` attribute, which ensures that the initial HTML is not visible.
To support the use of LegacyHidden as a true fragment, without an extra
DOM node, we will have to hide the initial HTML in some other way.
2020-05-25 18:16:53 -07:00
Brian Vaughn 8f4dc3e5d0 Warn if MutableSource snapshot is a function (#18933)
* Warn if MutableSource snapshot is a function

useMutableSource does not properly support snapshots that are functions. In part this is because of how it is implemented internally (the function gets mistaken for a state updater function). To fix this we could just wrap another function around the returned snapshot, but this pattern seems problematic to begin with- because the function that gets returned might itself close over mutable values, which would defeat the purpose of using the hook in the first place.

This PR proposes adding a new DEV warning if the snapshot returned is a function. It does not change the behavior (meaning that a function could still work in some cases- but at least the current behavior prevents passing around a closure that may later become stale unless you're really intentional about it e.g. () => () => {...}).

* Replaced .warn with .error
2020-05-21 16:14:29 -07:00
Brian Vaughn 142d4f1c00 useMutableSource hydration support (#18771)
* useMutableSource hydration support

* Remove unnecessary ReactMutableSource fork

* Replaced root.registerMutableSourceForHydration() with mutableSources option

* Response to PR feedback:

1. Moved mutableSources root option to hydrationOptions object
2. Only initialize root mutableSourceEagerHydrationData if supportsHydration config is true
3. Lazily initialize mutableSourceEagerHydrationData on root object
2020-05-21 16:00:46 -07:00
Brian Vaughn aefb97e6bb DevTools: Add root and renderer version to inspected props panel (#18963)
* DevTools: Add root and renderer version to inspected props panel
* Removed redundant .length check
2020-05-21 14:40:49 -07:00
Andrew Clark 74394aa8cb Add unstable_isNewReconciler to dispatcher (#18975)
This is a bit gross but I need to be able to access it without importing
the renderer.

There might be a better way but I need this to unblock internal bugfix.
2020-05-21 11:56:00 -07:00
Dominic Gannaway 730ae7afa2 Clear fiber.sibling field when clearing nextEffect (#18970)
* Clear fiber.sibling field when clearing nextEffect
2020-05-21 18:53:56 +01:00
Brian Vaughn 22f7663f14 Profiler: Don't count timed out (hidden) subtrees in base duration (#18966) 2020-05-20 18:36:57 -07:00
Sebastian Markbåge a30a1c6ef3 Transfer actualDuration only once for SuspenseList (#18959) 2020-05-20 15:12:38 -07:00
Andrew Clark 8b3b5c3524 Bugfix: Missing mode check in resetChildLanes (#18961)
Deferring a hidden tree is only supported in Concurrent Mode.

The missing check leads to an infinite loop when an update is scheduled
inside a hidden tree, because the pending work never gets reset.

This "accidentally" worked in the old reconciler because the heurstic
we used to detect offscreen trees was if `childExpirationTime`
was `Never`.

In the new reconciler, we check the tag instead. Which means we also
need to check the mode, like we do in the begin phase.

We should move this check out of the hot path. It shouldn't have been
in the hot path of the old reconciler, either.

Probably by moving `resetChildLanes` into the switch statement
in ReactFiberCompleteWork.
2020-05-19 23:10:49 -07:00
Andrew Clark 95ea8ed47c LegacyHidden: mode that defers without hiding (#18958)
Need this to unblock www. Not sure yet how we'll support this properly
long term.

While adding this, I noticed that the normal "hidden" mode of
LegacyHidden doesn't work properly because it doesn't toggle the
visibility of newly inserted nodes. This is fine for now since we only
use it via a userspace abstraction that wraps the children in an
additional node. But implementing this correctly is required for us
to start using it like a fragment, without the wrapper node.
2020-05-19 15:58:02 -07:00
Sebastian Silbermann c390ab3643 Add test for displayName on React.memo components (#18925)
* Add test for displayName on React.memo components

* Added extra memo displayName test

Co-authored-by: Brian Vaughn <brian.david.vaughn@gmail.com>
2020-05-15 15:56:50 -07:00
Sophie Alpert 21dc41c320 Simplify logic for mutable workInProgressSources (#18920)
isPrimaryRenderer is always constant for a given React build, so these two arrays do nothing.
2020-05-14 14:30:44 -07:00
Andrew Clark 0fb747f368 Add LegacyHidden to server renderer (#18919)
* Add LegacyHidden to server renderer

When the tree is hidden, the server renderer renders nothing. The
contents will be completely client rendered.

When the tree is visible it acts like a fragment.

The future streaming server renderer may want to pre-render these trees
and send them down in chunks, as with Suspense boundaries.

* Force client render, even at Offscreen pri
2020-05-14 11:28:11 -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
Andrew Clark fdb641629e Fix useMutableSource tearing bug (#18912)
* Failing useMutableSource test

If a source is mutated after initial read but before subscription is set
up, it should still entangle all pending mutations even if snapshot of
new subscription happens to match.

Test case illustrates how not doing this can lead to tearing.

* Fix useMutableSource tearing bug

Fix is to move the entanglement call outside of the block that checks
if the snapshot has changed.
2020-05-13 14:28:17 -07:00
Andrew Clark 33589f7423 useMutableSource: "Entangle" instead of expiring (#18889)
* useMutableSource: "Entangle" instead of expiring

A lane is said to be entangled with another when it's not allowed to
render in a batch that does not also include the other lane.

This commit implements entanglement for `useMutableSource`. If a source
is mutated in between when it's read in the render phase, but before
it's subscribed to in the commit phase, we must account for whether the
same source has pending mutations elsewhere. The old subscriptions must
not be allowed to re-render without also including the new subscription
(and vice versa), to prevent tearing.

In the old reconciler, we did this by synchronously flushing all the
pending subscription updates. This works, but isn't ideal. The new
reconciler can entangle the updates without de-opting to sync.

In the future, we plan to use this same mechanism for other features,
like skipping over intermediate useTransition states.

* Use clz instead of ctrz to pick an arbitrary lane

Should be slightly faster since most engines have built-in support.
2020-05-13 11:33:32 -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
Sebastian Markbåge 539527b642 Don't cut off effects at end of list if hydrating (#18872) 2020-05-08 21:26:51 -07:00
Andrew Clark 6edaf6f764 Detect and prevent render starvation, per lane (#18864)
* Detect and prevent render starvation, per lane

If an update is CPU-bound for longer than expected according to its
priority, we assume it's being starved by other work on the main thread.

To detect this, we keep track of the elapsed time using a fixed-size
array where each slot corresponds to a lane. What we actually store is
the event time when the lane first became CPU-bound.

Then, when receiving a new update or yielding to the main thread, we
check how long each lane has been pending. If the time exceeds a
threshold constant corresponding to its priority, we mark it as expired
to force it to synchronously finish.

We don't want to mistake time elapsed while an update is IO-bound
(waiting for data to resolve) for time when it is CPU-bound. So when a
lane suspends, we clear its associated event time from the array. When
it receives a signal to try again, either a ping or an update, we assign
a new event time to restart the clock.

* Store as expiration time, not start time

I originally stored the start time because I thought I could use this
in the future to also measure Suspense timeouts. (Event times are
currently stored on each update object for this purpose.) But that
won't work because in the case of expiration times, we reset the clock
whenever the update becomes IO-bound. So to replace the per-update
field, I'm going to have to track those on the room separately from
expiration times.
2020-05-08 12:47:51 -07:00
Luna Ruan df14b5bcc1 add new IDs for each each server renderer instance and prefixes to distinguish between each server render (#18576)
There is a worry that `useOpaqueIdentifier` might run out of unique IDs if running for long enough. This PR moves the unique ID counter so it's generated per server renderer object instead. For people who render different subtrees, this PR adds a prefix option to `renderToString`, `renderToStaticMarkup`, `renderToNodeStream`, and `renderToStaticNodeStream` so identifiers can be differentiated for each individual subtree.
2020-05-07 20:46:27 -07:00
Sebastian Markbåge edf6eac8a1 Don't cut off the tail of a SuspenseList if hydrating (#18854) 2020-05-06 23:51:46 -07:00
Sebastian Markbåge 55f5cdee01 Disable setState before mount in legacy mode (#18851)
We kind of "support" this pattern in legacy mode. It's only deprecated in
Concurrent Mode.
2020-05-06 20:30:59 -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
Sebastian Markbåge 96f3b7d1c3 Warn if calling setState outside of render but before commit (#18838)
* Don't attempt to render the children of a dehydrated Suspense boundary

The DehydratedFragment tag doesn't exist so doing so throws.

This can happen if we schedule childExpirationTime on the boundary and
bail out.

* Warn if scheduling work on a component before it is committed
2020-05-06 09:45:35 -07:00
Fernando Lores 40e6029462 wrap SuspenseInstanceRetry callback so scheduler waits for it (#18805) 2020-05-05 12:47:49 -07:00
Brian Vaughn 3cde22a84e Experimental test selector API (#18607)
Adds several new experimental APIs to aid with automated testing.

Each of the methods below accepts an array of "selectors" that identifies a path (or paths) through a React tree. There are four basic selector types:

* Component: Matches Fibers with the specified React component type
* Role: Matches Host Instances matching the (explicit or implicit) accessibility role.
* Test name: Matches Host Instances with a data-testname attribute.
* Text: Matches Host Instances that directly contain the specified text.
* There is also a special lookahead selector type that enables further matching within a path (without actually including the path in the result). This selector type was inspired by the :has() CSS pseudo-class. It enables e.g. matching a <section> that contained a specific header text, then finding a like button within that <section>.

API
* findAllNodes(): Finds all Host Instances (e.g. HTMLElement) within a host subtree that match the specified selector criteria.
* getFindAllNodesFailureDescription(): Returns an error string describing the matched and unmatched portions of the selector query.
* findBoundingRects(): For all React components within a host subtree that match the specified selector criteria, return a set of bounding boxes that covers the bounds of the nearest (shallowed) Host Instances within those trees.
* observeVisibleRects(): For all React components within a host subtree that match the specified selector criteria, observe if it’s bounding rect is visible in the viewport and is not occluded.
* focusWithin(): For all React components within a host subtree that match the specified selector criteria, set focus within the first focusable Host Instance (as if you started before this component in the tree and moved focus forwards one step).
2020-05-05 10:37:46 -07:00
Andrew Clark fe7163e73d Add unstable prefix to experimental APIs (#18825)
We've been shipping unprefixed experimental APIs (like `createRoot` and
`useTransition`) to the Experimental release channel, with the rationale
that because these APIs do not appear in any stable release, we're free
to change or remove them later without breaking any downstream projects.

What we didn't consider is that downstream projects might be tempted to
use feature detection:

```js
const useTransition = React.useTransition || fallbackUseTransition;
```

This pattern assumes that the version of `useTransition` that exists in
the Experimental channel today has the same API contract as the final
`useTransition` API that we'll eventually ship to stable.

To discourage feature detection, I've added an `unstable_` prefix to
all of our unstable APIs.

The Facebook builds still have the unprefixed APIs, though. We will
continue to support those; if we make any breaking changes, we'll
migrate the internal callers like we usually do. To make testing easier,
I added the `unstable_`-prefixed APIs to the www builds, too. That way
our tests can always use the prefixed ones without gating on the
release channel.
2020-05-04 22:25:41 -07:00
Sebastian Markbåge cd4a96035f Remove old CM exports (#18710) 2020-05-04 21:39:57 -07:00
Dan Abramov 3e13d70984 [RN] Remove debugging invariant (#18813) 2020-05-04 15:48:35 +01:00
Dan Abramov d830cd9984 [Blocks] Fix stale data on updates (#18810)
* [Blocks] Failing test for nested load

* Simplify the test

* Add a similar test that fails in PROD

* Copy .type when cloning work in progress
2020-05-04 01:43:51 +01:00