Commit Graph

582 Commits

Author SHA1 Message Date
Andrew Clark 82c8fa90be Add back useMutableSource temporarily (#22396)
Recoil uses useMutableSource behind a flag. I thought this was fine
because Recoil isn't used in any concurrent roots, so the behavior
would be the same, but it turns out that it is used by concurrent
roots in a few places.

I'm not expecting it to be hard to migrate to useSyncExternalStore, but
to de-risk the change I'm going to roll it out gradually with a flag. In
the meantime, I've added back the useMutableSource API.
2021-09-21 20:38:24 -07:00
Andrew Clark 86b3e2461d Implement useSyncExternalStore on server (#22347)
Adds a third argument called `getServerSnapshot`.

On the server, React calls this one instead of the normal `getSnapshot`.
We also call it during hydration.

So it represents the snapshot that is used to generate the initial,
server-rendered HTML. The purpose is to avoid server-client mismatches.
What we render during hydration needs to match up exactly with what we
render on the server.

The pattern is for the server to send down a serialized copy of the
store that was used to generate the initial HTML. On the client, React
will call either `getSnapshot` or `getServerSnapshot` on the client as
appropriate, depending on whether it's currently hydrating.

The argument is optional for fully client rendered use cases. If the
user does attempt to omit `getServerSnapshot`, and the hook is called
on the server, React will abort that subtree on the server and
revert to client rendering, up to the nearest Suspense boundary.

For the userspace shim, we will need to use a heuristic (canUseDOM)
to determine whether we are in a server environment. I'll do that in
a follow up.
2021-09-20 08:31:02 -07:00
Andrew Clark 8209de2695 Delete useMutableSource implementation (#22292)
This API was replaced by useSyncExternalStore
2021-09-19 21:11:50 -07:00
Ricky 263cfa6ecb [Experimental] Add useInsertionEffect (#21913) 2021-09-14 10:27:09 -04:00
Konstantin Popov 86c7ca70a9 Fix link (#22296)
Fix link (branch master was renamed to main): 

master -> main
2021-09-12 11:09:53 -04:00
salazarm a3fde23588 Detect subscriptions wrapped in startTransition (#22271)
* Detect subscriptions wrapped in startTransition
2021-09-08 17:01:09 -04:00
Andrew Clark 77912d9a05 Wire up the native API for useSyncExternalStore (#22237)
Adds useSyncExternalStore to the internal dispatcher, and exports
the native API from the React package without yet implementing it.
2021-09-07 10:20:24 -07:00
Jianhua Zheng b8884de24e break up import keyword to avoid being accidentally parsed as dynamic import statement in external code (#21918)
Co-authored-by: zhengjianhua <zhengjianhua.michael@bytedance.com>
2021-09-06 21:20:33 +01:00
Luna Ruan fc40f02adb Add consoleManagedByDevToolsDuringStrictMode feature flag in React Reconciler (#22196) 2021-09-01 11:56:52 -07:00
Luna Ruan 60a30cf32e Console Logging for StrictMode Double Rendering (#22030)
React currently suppress console logs in StrictMode during double rendering. However, this causes a lot of confusion. This PR moves the console suppression logic from React into React Devtools. Now by default, we no longer suppress console logs. Instead, we gray out the logs in console during double render. We also add a setting in React Devtools to allow developers to hide console logs during double render if they choose.
2021-08-25 15:35:38 -07:00
Bowen fc3b6a4118 Fix a few typos (#22154)
Co-authored-by: Bowen Li <bowen31337@gmail.com>
2021-08-22 14:11:35 -04:00
Brian Vaughn 9eb2aaaf81 Fixed ReactSharedInternals export in UMD bundle (#22117) 2021-08-18 01:40:55 -04:00
Ehsan Hosseini 464f275724 Update link to flow (#21862)
`main` branch does not exist in the `flow` project and it is `master`.

Co-authored-by: Ehsan Hosseini <53467610+dh-hosseini@users.noreply.github.com>
2021-07-13 10:55:54 -04:00
Andrew Clark a4ecd85e86 act: Batch updates, even in legacy roots (#21797)
In legacy roots, if an update originates outside of `batchedUpdates`,
check if it's inside an `act` scope; if so, treat it as if it were
batched. This is only necessary in legacy roots because in concurrent
roots, updates are batched by default.

With this change, the Test Utils and Test Renderer versions of `act` are
nothing more than aliases of the isomorphic API (still not exposed, but
will likely be the recommended API that replaces the others).
2021-07-12 17:15:20 -07:00
Brian Vaughn d483463bc8 Updated scripts and config to replace "master" with "main" branch (#21768) 2021-06-29 14:26:24 -04:00
Andrew Clark cae635054e act: Resolve to return value of scope function (#21759)
When migrating some internal tests I found it annoying that I couldn't
return anything from the `act` scope. You would have to declare the
variable on the outside then assign to it. But this doesn't play well
with type systems — when you use the variable, you have to check
the type.

Before:

```js
let renderer;
act(() => {
  renderer = ReactTestRenderer.create(<App />);
})

// Type system can't tell that renderer is never undefined
renderer?.root.findByType(Component);
```

After:

```js
const renderer = await act(() => {
  return ReactTestRenderer.create(<App />);
})
renderer.root.findByType(Component);
```
2021-06-26 11:51:23 -07:00
Dan Abramov 51b0becf3e Always keep disabled logs in the second pass (#21739)
* Add tests for disabled logs

* Always keep disabled logs in the second pass

* Jest nit

* Always use the second result
2021-06-24 19:50:07 +01:00
Andrew Clark d7dce572c7 Remove internal act builds from public modules (#21721)
* Move internal version of act to shared module

No reason to have three different copies of this anymore.

I've left the the renderer-specific `act` entry points because legacy
mode tests need to also be wrapped in `batchedUpdates`. Next, I'll update
the tests to use `batchedUpdates` manually when needed.

* Migrates tests to use internal module directly

Instead of the `unstable_concurrentAct` exports. Now we can drop those
from the public builds.

I put it in the jest-react package since that's where we put our other
testing utilities (like `toFlushAndYield`). Not so much so it can be
consumed publicly (nobody uses that package except us), but so it works
with our build tests.

* Remove unused internal fields

These were used by the old act implementation. No longer needed.
2021-06-22 14:29:35 -07: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
Andrew Clark bd0a963445 Throw when act is used in production (#21686)
Upgrades the deprecation warning to a runtime error.

I did it this way instead of removing the export so the type is the same
in both builds. It will get dead code eliminated regardless.
2021-06-16 16:29:51 -04:00
Sebastian Markbåge 5aa0c5671f Fix Issue with Undefined Lazy Imports By Refactoring Lazy Initialization Order (#21642)
* Add a DEV warning for common case

* Don't set Pending flag before we know it's a promise

* Move default exports extraction to render phase

This is really where most unwrapping happen. The resolved promise is the
module object and then we read things from it.

This way it lines up a bit closer with the Promise model too since the
promise resolving to React gets passed this same value.

If this throws, then it throws during render so it's caught properly and
you can break on it and even see it on the right stack.

* Check if the default is in the module object instead of if it's undefined

Normally we'd just check if something is undefined but in this case it's
valid to have an undefined value in the export but if you don't have a
property then you're probably importing the wrong kind of object.

* We need to check if it's uninitialized for sync resolution

Co-authored-by: Dan Abramov <dan.abramov@me.com>
2021-06-07 14:47:18 -07:00
Sebastian Markbåge a8a4742f1c Convert ES6/TypeScript/CoffeeScript Tests to createRoot + act (#21598)
* Convert ES6/TypeScript CoffeeScript Tests to createRoot + act

* Change expectation for WWW+VARIANT because the deferRenderPhaseUpdateToNextBatch flag breaks this behavior
2021-06-02 11:36:59 -07:00
Andrew Clark e16d61c300 [Offscreen] Mount/unmount layout effects (#21386)
* [Offscreen] Mount/unmount layout effects

Exposes the Offscreen component type and implements basic support for
mount/unmounting layout effects when the visibility is toggled.

Mostly it works the same way as hidden Suspense trees, which use the
same internal fiber type. I had to add an extra bailout, though, that
doesn't apply to the Suspense case but does apply to Offscreen
components: a hidden Offscreen tree will eventually render at low
priority, and when we it does, its `subtreeTag` will have effects
scheduled on it. So I added a check to the layout phase where, if the
subtree is hidden, we skip over the subtree entirely. An alternate
design would be to clear the subtree flags in the render phase, but I
prefer doing it this way since it's harder to mess up.

We also need an API to enable the same thing for passive effects. This
is not yet implemented.

* Add test starting from hidden

Co-authored-by: Rick Hanlon <rickhanlonii@gmail.com>
2021-06-01 12:46:08 -07:00
Sebastian Silbermann 3c2341416a Update jest to v26 (#21574)
* Install jest 26

* jsdom env now uses 16 by default

* require.requireActual -> jest.requireActual

* deduplicate added deps
2021-05-27 16:33:57 +01: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 e9a4a44aae Add back root override for strict mode (#21428)
* Add back root override for strict mode

* Switch flag to boolean

* Fix flow
2021-05-04 15:42:48 -04:00
Brian Vaughn d1542de3a6 Unify React.memo and React.forwardRef display name logic (#21392)
Co-authored-by: iChenLei <2470828450@qq.com>
2021-05-04 11:40:16 -04:00
Brian Vaughn 9a130e1dec StrictMode includes strict effects by default (#21418)
Removed "unstable_level" attribute support for the time being.
2021-05-04 09:47:06 -04:00
Brian Vaughn 15fb8c3045 createRoot API is no longer strict by default (#21417) 2021-05-03 16:57:03 -04:00
Brian Vaughn fc33f12bde Remove unstable scheduler/tracing API (#20037) 2021-04-26 19:16:18 -04:00
Ricky a632f7de3b Flip tuple order of useTransition (#20976) 2021-04-20 12:21:44 -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
Sebastian Silbermann 75c616554d Include actual type of Profiler#id on type mismatch (#20306) 2021-04-08 13:36:42 -04:00
Sebastian Markbåge 172e89b4bf Reland Remove redundant initial of isArray (#21188)
* Remove redundant initial of isArray (#21163)

* Reapply prettier

* Type the isArray function with refinement support

This ensures that an argument gets refined just like it does if isArray is
used directly.

I'm not sure how to express with just a direct reference so I added a
function wrapper and confirmed that this does get inlined properly by
closure compiler.

* A few more

* Rename unit test to internal

This is not testing a bundle.

Co-authored-by: Behnam Mohammadi <itten@live.com>
2021-04-07 07:57:43 -07:00
Sebastian Markbage b4f119cdf1 Revert "Remove redundant initial of isArray (#21163)"
This reverts commit b130a0f5cd.
2021-04-01 15:19:00 -04:00
Behnam Mohammadi b130a0f5cd Remove redundant initial of isArray (#21163) 2021-04-01 10:50:48 -07:00
Behnam Mohammadi 2c9fef32db Remove redundant initial of hasOwnProperty (#21134)
* remove redundant initial of hasOwnProperty

* remove redundant initial of hasOwnProperty part 2

* remove redundant initial of hasOwnProperty part 3
2021-04-01 09:05:10 -07:00
Andrew Clark f8ef4ff571 Flush discrete passive effects before paint (#21150)
If a discrete render results in passive effects, we should flush them
synchronously at the end of the current task so that the result is
immediately observable. For example, if a passive effect adds an event
listener, the listener will be added before the next input.

We don't need to do this for effects that don't have discrete/sync
priority, because we assume they are not order-dependent and do not
need to be observed by external systems.

For legacy mode, we will maintain the existing behavior, since it hasn't
been reported as an issue, and we'd have to do additional work to
distinguish "legacy default sync" from "discrete sync" to prevent all
passive effects from being treated this way.
2021-03-31 10:39:19 -07:00
Andrew Clark 3ba5c87377 Remove Scheduler indirection (#21107)
* Bump version number

* Remove Scheduler indirection

I originally kept the React PriorityLevel and Scheduler PriorityLevel
types separate in case there was a versioning mismatch between the two
modules. However, it looks like we're going to keep the Scheduler module
private in the short to medium term, and longer term the public
interface will match postTask. So, I've removed the extra indirection
(the switch statements that convert between the two types).
2021-03-28 14:13:38 -07:00
Andrew Clark 03ede83d2e Use EventPriority to track update priority (#21082)
Instead of LanePriority. Internally, EventPriority is just a lane, so
this skips an extra conversion. Since EventPriority is a "public" (to
the host config) type, I was also able to remove some deep imports
of the Lane module.

This gets us most of the way to deleting the LanePriority entirely.
2021-03-25 09:21:41 -07:00
Ricky ca99ae97b4 Replace some flushExpired callsites (#20975) 2021-03-22 12:44:19 -04:00
Andrew Clark 6d3ecb70dc Remove unstable_changedBits (#20953)
We added this unstable feature a few years ago, as a way to opt out of
context updates, but it didn't prove useful in practice.

We have other proposals for how to address the same problem, like
context selectors.

Since it was prefixed with `unstable_`, we should be able to remove it
without consequence. The hook API already warned if you used it.

Even if someone is using it somewhere, it's meant to be an optimization
only, so if they are using the API properly, it should not have any
semantic impact.
2021-03-19 15:36:51 -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 60182d64ca Cleanup tests using runWithPriority. (#20958)
* Remove Scheduler.runWithPriority from some tests

* Mark experimental test experimental
2021-03-10 12:44:25 -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
Brian Vaughn 7df65725ba Split getComponentName into getComponentNameFromFiber and getComponentNameFromType (#20940)
Split getComponentName into getComponentNameFromFiber and getComponentNameFromType
2021-03-05 16:02:02 -05: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
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