Commit Graph
138 Commits
Author SHA1 Message Date
Sebastian MarkbågeandGitHub 849ec7f355 [Debug Tools] Always use includeHooksSource option (#28309)
This option was added defensively but it's not needed. There's no cost
to including it always.

I suspect this optional was added mainly to avoid needing to update
tests. That's not a reason to have an unnecessary public API though.

We have a praxis for dealing with source location in tests to avoid them
failing tests. I also ported them to inline snapshots so that additions
to the protocol isn't such a pain.
2024-02-14 11:07:35 -05:00
Andrew ClarkandGitHub 68e6bc4171 Revert "[Tests] Reset modules by default" (#28318)
This was causing a slowdown in one of the tests
ESLintRuleExhaustiveDeps-test.js. Reverting until we figure out why.
2024-02-13 11:39:45 -05:00
danandGitHub 35a6b9c85a Switch <Context> to mean <Context.Provider> (#28226)
Previously, `<Context>` was equivalent to `<Context.Consumer>`. However,
since the introduction of Hooks, the `<Context.Consumer>` API is rarely
used. The goal here is to make the common case cleaner:

```js
const ThemeContext = createContext('light')

function App() {
  return (
    <ThemeContext value="dark">
      ...
    </ThemeContext>
  )
}

function Button() {
  const theme = use(ThemeContext)
  // ...
}
```

This is technically a breaking change, but we've been warning about
rendering `<Context>` directly for several years by now, so it's
unlikely much code in the wild depends on the old behavior. [Proof that
it warns today (check
console).](https://codesandbox.io/p/sandbox/peaceful-nobel-pdxtfl)

---

**The relevant commit is 5696782b428a5ace96e66c1857e13249b6c07958.** It
switches `createContext` implementation so that `Context.Provider ===
Context`.

The main assumption that changed is that a Provider's fiber type is now
the context itself (rather than an intermediate object). Whereas a
Consumer's fiber type is now always an intermediate object (rather than
it being sometimes the context itself and sometimes an intermediate
object).

My methodology was to start with the relevant symbols, work tags, and
types, and work my way backwards to all usages.

This might break tooling that depends on inspecting React's internal
fields. I've added DevTools support in the second commit. This didn't
need explicit versioning—the structure tells us enough.
2024-02-13 10:04:49 -05:00
Sebastian MarkbågeandGitHub 57b57ee3fb [Debug Tools] Introspect Promises in use() (#28297)
Alternative to #28295.

Instead of stashing all of the Usables eagerly, we can extract them by
replaying the render when we need them like we do with any other hook.
We already had an implementation of `use()` but it wasn't quite
complete.

These can also include further DebugInfo on them such as what Server
Component rendered the Promise or async debug info. This is nice just to
see which use() calls were made in the side-panel but it can also be
used to gather everything that might have suspended.

Together with https://github.com/facebook/react/pull/28286 we cover the
case when a Promise was used a child and if it was unwrapped with use().
Notably we don't cover a Promise that was thrown (although we do support
that in a Server Component which maybe we shouldn't). Throwing a Promise
isn't officially supported though and that use case should move to the
use() Hook.

The pattern of conditionally suspending based on cache also isn't really
supported with the use() pattern. You should always call use() if you
previously called use() with the same input. This also ensures that we
can track what might have suspended rather than what actually did.

One limitation of this strategy is that it's hard to find all the places
something might suspend in a tree without rerendering all the fibers
again. So we might need to still add something to the tree to indicate
which Fibers may have further debug info / thenables.
2024-02-12 17:54:28 -05:00
Sebastian SilbermannandGitHub 45381a1e24 DevTools: Add support for use(Context) (#28233) 2024-02-08 18:47:40 +01:00
RickyandGitHub 1a5d7dd130 [Tests] Reset modules by default (#28254)
## Overview

Sets `resetModules: true` in the base Jest config, and deletes all the
`jest.resetModule()` calls we don't need.
2024-02-06 12:43:27 -05:00
Sebastian SilbermannandGitHub 84d4d3db04 DevTools: Add support for useFormState (#28232)
## Summary

Add support for `useFormState` Hook fixing "Unsupported hook in the
react-debug-tools package: Missing method in Dispatcher: useFormState"
when inspecting components using `useFormState`

## How did you test this change?

- Added test to ReactHooksInspectionIntegration
- Added dedicated section for form actions to devtools-shell
![Screenshot 2024-02-04 at 12 02
05](https://github.com/facebook/react/assets/12292047/bb274789-64b8-4594-963e-87c4b6962144)
2024-02-05 15:39:45 +01:00
Sebastian SilbermannandGitHub 3e34152524 DevTools: Add support for useOptimistic Hook (#27982)
## Summary

Add support for `useOptimistic` Hook fixing "Unsupported hook in the
react-debug-tools package: Missing method in Dispatcher: useOptimistic"
when inspecting components using `useOptimistic`

## How did you test this change?

- Added test following the same pattern as for `useDeferredValue`
2024-02-02 23:18:16 +01:00
Jack PopeandGitHub 737e8c74da Add stable concurrent option to react-test-renderer (#27804)
## Summary

Concurrent rendering has been the default since React 18 release.
ReactTestRenderer requires passing `{unstable_isConcurrent: true}` to
match this behavior, which means by default tests written with RTR use a
different rendering method than the code they test.

Eventually, RTR should only use ConcurrentRoot. As a first step, let's
add a version of the concurrent option that isn't marked unstable. Next
we will follow up with removing the unstable option when it is safe to
merge.

## How did you test this change?

`yarn test
packages/react-test-renderer/src/__tests__/ReactTestRendererAsync-test.js`
2023-12-07 10:26:33 -05:00
Jan KassensandGitHub 47f5185b3f Flow: make more objects exact (#27790)
This makes a couple objects more exact. Nothing critical, just noticed
this old branch I had created when doing some Flow upgrades in the past.
2023-12-04 16:10:36 -05:00
Ruslan LesiutinandGitHub 843fd4c9e1 fix[devtools/useMemoCache]: implement a working copy of useMemoCache (#27659)
In https://github.com/facebook/react/pull/27472 I've removed broken
`useMemoCache` implementation and replaced it with a stub. It actually
produces errors when trying to inspect components, which are compiled
with Forget.

The main difference from the implementation in
https://github.com/facebook/react/pull/26696 is that we are using
corresponding `Fiber` here, which has patched `updateQueue` with
`memoCache`. Previously we would check it on a hook object, which
doesn't have `updateQueue`.

Tested on pages, which are using Forget and by inspecting elements,
which are transpiled with Forget.
2023-11-14 18:23:39 +00:00
Ruslan LesiutinandGitHub 5dacb7d29d fix[devtools/useMemoCache]: add stub for useMemoCache in ReactDebugHook (#27472)
Currently, we have this error in our logs of the internal version of
React DevTools:
```
TypeError: Cannot read properties of undefined (reading 'memoCache')
    at Proxy.useMemoCache (chrome-extension://dnjnjgbfilfphmojnmhliehogmojhclc/build/react_devtools_backend_compact.js:151:71)
```

Looking at the build files of the extension, it fails here:
https://github.com/facebook/react/blob/d4ab5627001d0dd61fb1b170c1a515a7dba6148b/packages/react-debug-tools/src/ReactDebugHooks.js#L333-L337

Looks like `updateQueue` can be `undefined`, as it is not defined in
hook object here:
https://github.com/facebook/react/blob/d4ab5627001d0dd61fb1b170c1a515a7dba6148b/packages/react-reconciler/src/ReactFiberHooks.js#L180-L186

~~Also, it looks like `useMemoCache` implementation doesn't expect this,
so it should also result into TypeError here, line 1114:~~

https://github.com/facebook/react/blob/d4ab5627001d0dd61fb1b170c1a515a7dba6148b/packages/react-reconciler/src/ReactFiberHooks.js#L1108-L1115

~~Should this also be updated?~~
2023-10-17 18:39:10 +01:00
Andrew ClarkandGitHub cbcd222dca 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
Noah LemenandGitHub aa5a862d19 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
laurenandGitHub 2bfc9cbecb [DevTools] Add support for useMemoCache (#26696)
useMemoCache wasn't previously supported in the DevTools, so any attempt
to inspect a component using the hook would result in a
`dispatcher.useMemoCache is not a function (it is undefined)` error.
2023-04-25 09:19:25 -07:00
Andrew ClarkandGitHub a6a29acf7a Clean up enableUseHook flag (#26707)
This has been statically enabled everywhere for months.
2023-04-23 14:50:17 -04:00
Sophie AlpertandGitHub 50572a1e0e Use .slice() for all substring-ing (#26677)
- substr is Annex B
- substring silently flips its arguments if they're in the "wrong order", which is confusing
- slice is better than sliced bread (no pun intended) and also it works the same way on Arrays so there's less to remember

---

> I'd be down to just lint and enforce a single form just for the potential compression savings by using a repeated string.

_Originally posted by @sebmarkbage in https://github.com/facebook/react/pull/26663#discussion_r1170455401_
2023-04-19 14:26:01 -07:00
Jan KassensandGitHub ea7805058c [flow] make Flow suppressions explicit on the error (#26487)
Added an explicit type to all $FlowFixMe suppressions to reduce
over-suppressions of new errors that might be caused on the same lines.

Also removes suppressions that aren't used (e.g. in a `@noflow` file as
they're purely misleading)

Test Plan:
yarn flow-ci
2023-03-27 13:43:04 +02:00
1b58ee1dbd Update more tests to not rely on sync queuing (#26358)
This fixes a handful of tests that were accidentally relying on React
synchronously queuing work in the Scheduler after a setState.

Usually this is because they use a lower level SchedulerMock method
instead of either `act` or one of the `waitFor` helpers. In some cases,
the solution is to switch to those APIs. In other cases, if we're
intentionally testing some lower level behavior, we might have to be a
bit more clever.

Co-authored-by: Tianyu Yao <[email protected]>
2023-03-10 11:06:28 -05:00
Andrew ClarkandGitHub df7d322402 Codemod redundant async act scopes (#26350)
Prior to #26347, our internal `act` API (not the public API) behaved
differently depending on whether the scope function returned a promise
(i.e. was an async function), for historical reasons that no longer
apply. Now that this is fixed, I've codemodded all async act scopes that
don't contain an await to be sync.

No pressing motivation other than it looks nicer and the codemod was
easy. Might help avoid confusion for new contributors who see async act
scopes with nothing async inside and infer it must be like that for a
reason.
2023-03-08 16:40:23 -05:00
Andrew ClarkandGitHub 6f6a41da6d Move internalAct to internal-test-utils package (#26344)
This is not a public API. We only use it for our internal tests, the
ones in this repo. Let's move it to this private package. Practically
speaking this will also let us use async/await in the implementation.
2023-03-08 12:58:31 -05:00
Andrew ClarkandGitHub d86bd82696 Codemod act -> await act (4/?) (#26338)
Similar to the rationale for `waitFor` (see #26285), we should always
await the result of an `act` call so that microtasks have a chance to
fire.

This only affects the internal `act` that we use in our repo, for now.
In the public `act` API, we don't yet require this; however, we
effectively will for any update that triggers suspense once `use` lands.
So we likely will start warning in an upcoming minor.
2023-03-08 11:36:05 -05:00
Andrew ClarkandGitHub 346d17951e Codemod act -> await act (1/?) (#26334)
Similar to the rationale for `waitFor` (see
https://github.com/facebook/react/pull/26285), we should always await
the result of an `act` call so that microtasks have a chance to fire.

This only affects the internal `act` that we use in our repo, for now.
In the public `act` API, we don't yet require this; however, we
effectively will for any update that triggers suspense once `use` lands.
So we likely will start warning in an upcoming minor.
2023-03-07 10:15:34 -05:00
Andrew ClarkandGitHub d4d43073e3 Codemod tests to waitFor pattern (2/?) (#26296)
This converts some of our test suite to use the `waitFor` test pattern,
instead of the `expect(Scheduler).toFlushAndYield` pattern. Most of
these changes are automated with jscodeshift, with some slight manual
cleanup in certain cases.

See #26285 for full context.
2023-03-03 17:01:57 -05:00
Jan KassensandGitHub 1aa5d9cf56 [flow] enable LTI inference mode (#26104)
This is the next generation inference mode for Flow.
2023-02-09 17:07:39 -05:00
Jan KassensandGitHub 77a81a7182 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 KassensandGitHub 5e0b1975a7 [flow] enable exact_empty_objects (#25973)
This enables the "exact_empty_objects" setting for Flow which makes
empty objects exact instead of building up the type as properties are
added in code below. This is in preparation to Flow 191 which makes this
the default and removes the config.

More about the change in the Flow blog
[here](https://medium.com/flow-type/improved-handling-of-the-empty-object-in-flow-ead91887e40c).
2023-01-09 17:00:36 -05:00
Jan KassensandGitHub 5d81201dc2 [flow] enable enforce_local_inference_annotations (#25921)
This setting is an incremental path to the next Flow version enforcing
type annotations on most functions (except some inline callbacks).

Used
```
node_modules/.bin/flow codemod annotate-functions-and-classes --write .
```
to add a majority of the types with some hand cleanup when for large
inferred objects that should just be `Fiber` or weird constructs
including `any`.

Suppressed the remaining issues.

Builds on #25918
2023-01-09 15:46:48 -05:00
Sebastian MarkbågeandGitHub 01880300fb 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
Andrew ClarkandGitHub 6dd316c347 [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
Sebastian MarkbågeandGitHub 55229d0c08 Split Cache into its own Dispatcher (#25474)
* Missing Hooks

* Remove www forks. These can use __SECRET... instead.

* Move cache to separate dispatcher

These will be available in more contexts than just render.
2022-10-12 23:13:39 -04:00
Jan Kassens 68adb0b4ea Flow: inference_mode=constrain_writes
This mode is going to be the new default in Flow going forward.
There was an unfortuante large number of suppressions in this update.

More on the changes can be found in this [Flow blog post](https://medium.com/flow-type/new-flow-language-rule-constrained-writes-4c70e375d190).

Added some of the required annotations using the provided codemod:

```sh
node_modules/.bin/flow codemod annotate-declarations --write .
```

ghstack-source-id: 0b168e1b23
Pull Request resolved: https://github.com/facebook/react/pull/25422
2022-10-04 15:49:48 -04:00
Tianyu YaoandGitHub 1ded5230b6 [DevTools] Check if Proxy exists before creating DispatcherProxy (#25278) 2022-09-16 11:24:03 -07:00
Jan KassensandGitHub dd23ef3d09 straightford explicit types (#25253) 2022-09-13 17:57:38 -04:00
Jan KassensandGitHub 81b1364ec6 Flow: remove explicit object syntax (#25223) 2022-09-09 16:03:48 -04:00
Jan KassensandGitHub 964b1fbdfc Flow: implicit-inexact-object=error (#25210)
* implicit-inexact-object=error
* default everything ambiguous to exact object
* inexact where exact causes errors
2022-09-09 10:13:58 -04:00
Jan KassensandGitHub b15362f887 Update to Flow from 0.97 to 0.122 (#25204)
* flow 0.122
* update ReactModel type
2022-09-08 11:46:07 -04:00
Sebastian SilbermannandGitHub f7bcfabe93 test(react-debug-tools): Improve coverage of currentDispatcher.current setter (#24945) 2022-07-21 15:46:43 -04:00
Mengdi ChenandGitHub b8bb20bb9e [DevTools] fix useDeferredValue to match reconciler change (#24742)
* [DevTools] fix useDeferredValue to match reconciler change

* fixup

* update test to catch original issue

* fix lint

* add safer tests for other composite hooks
2022-06-17 14:43:10 -04:00
Mengdi "Monday" ChenandGitHub 77232c2b02 [ReactDebugTools] wrap uncaught error from rendering user's component (#24216)
* [ReactDebugTools] wrap uncaught error from rendering user's component

* fix lint

* make error names more package specific

* update per review comments

* fix tests

* fix lint

* fix tests

* fix lint

* fix error name & nits

* try catch instead of mocking error

* fix test for older node.js version

* avoid false positive from try-catch in tests
2022-04-01 14:38:11 -04:00
Mengdi "Monday" ChenandGitHub a78fed8f7a [ReactDebugTools] add custom error type for future new hooks (#24168)
* [ReactDebugTools] add custom error type for future new hooks

* update per review comments

* remove unused argument
2022-03-30 11:07:12 -04:00
Andrew ClarkandGitHub e9cae7cff5 Add : to beginning and end of every useId (#23360)
The ids generated by useId are unique per React root. You can create
additional ids by concatenating them with locally unique strings.

To support this pattern, no id will ever be a subset of another id. We
achieve this by adding a special character to the beginning and end.

We use a colon (":") because it's uncommon — even if you don't prefix
the ids using the `identifierPrefix` option, collisions are unlikely.

One downside of a colon is that it's not a valid character in DOM
selectors, like `querySelectorAll`. We think this is probably
fine because it's not a common use case in React, and there are
workarounds or alternative solutions. But we're open to reconsidering
this in the future if there's a compelling argument.
2022-02-24 20:07:41 -05:00
Luna RuanandGitHub f20507c57f [DevTools][Transition Tracing] onTransitionComplete and onTransitionStart implmentation (#23313)
* add transition name to startTransition

Add a transitionName to start transition, store the transition start time and name in the batch config, and pass it to the root on render

* Transition Tracing Types and Consts

* Root begin work

The root operates as a tracing marker that has all transitions on it. This PR only tested the root with one transition so far

- Store transitions in memoizedState. Do this in updateHostRoot AND attemptEarlyBailoutIfNoScheduledUpdate. We need to do this in the latter part because even if the root itself doesn't have an update, it could still have new transitions in its transitionLanes map that we need to process.

* Transition Tracing commit phase

- adds a module scoped pending transition callbacks object that contains all transition callbacks that have not yet been processed. This  contains all callbacks before the next paint occurs.
- Add code in the mutation phase to:
        * For the root, if there are transitions that were initialized during this commit in the root transition lanes map, add a transition start call to the pending transition callbacks object. Then, remove the transitions from the root transition lanes map.
        * For roots, in the commit phase, add a transition complete call

We add this code in the mutation phase because we can't add it to the passive phase because then the paint might have occurred before we even know which callbacks to call

* Process Callbacks after paint

At the end of the commit phase, call scheduleTransitionCallbacks to schedule all pending transition callbacks to be called after paint. Then clear the callbacks
2022-02-24 14:28:18 -08:00
Sebastian MarkbågeandGitHub aa646de85f Remove object-assign polyfill (#23351)
* Remove object-assign polyfill

We really rely on a more modern environment where this is typically
polyfilled anyway and we don't officially support IE with more extensive
polyfilling anyway. So all environments should have the native version
by now.

* Use shared/assign instead of Object.assign in code

This is so that we have one cached local instance in the bundle.

Ideally we should have a compile do this for us but we already follow
this pattern with hasOwnProperty, isArray, Object.is etc.

* Transform Object.assign to now use shared/assign

We need this to use the shared instance when Object.spread is used.
2022-02-23 19:34:24 -05:00
Sebastian MarkbågeandGitHub a0d178bf8c Update the exports field (#23257)
* Add .browser and .node explicit entry points

This can be useful when the automatic selection doesn't work properly.

* Remove react/index

I'm not sure why I added this in the first place. Perhaps due to how our
builds work somehow.

* Remove build-info.json from files field
2022-02-08 21:07:26 -05:00
Andrew ClarkandGitHub 8e87e0cf1d Upgrade useId to alpha channel (#22674) 2021-11-01 15:26:42 -07:00
Andrew ClarkandGitHub fa6d79dcdc Remove experimental useOpaqueIdentifier API (#22672)
useId is the updated version of this API.
2021-11-01 15:02:39 -07:00
Andrew ClarkandGitHub a225a266b6 useId (#22644)
* Add useId to dispatcher

* Initial useId implementation

Ids are base 32 strings whose binary representation corresponds to the
position of a node in a tree.

Every time the tree forks into multiple children, we add additional bits
to the left of the sequence that represent the position of the child
within the current level of children.

    00101       00010001011010101
    ╰─┬─╯       ╰───────┬───────╯
  Fork 5 of 20       Parent id

The leading 0s are important. In the above example, you only need 3 bits
to represent slot 5. However, you need 5 bits to represent all the forks
at the current level, so we must account for the empty bits at the end.

For this same reason, slots are 1-indexed instead of 0-indexed.
Otherwise, the zeroth id at a level would be indistinguishable from
its parent.

If a node has only one child, and does not materialize an id (i.e. does
not contain a useId hook), then we don't need to allocate any space in
the sequence. It's treated as a transparent indirection. For example,
these two trees produce the same ids:

<>                          <>
  <Indirection>               <A />
    <A />                     <B />
  </Indirection>            </>
  <B />
</>

However, we cannot skip any materializes an id. Otherwise, a parent id
that does not fork would be indistinguishable from its child id. For
example, this tree does not fork, but the parent and child must have
different ids.

<Parent>
  <Child />
</Parent>

To handle this scenario, every time we materialize an id, we allocate a
new level with a single slot. You can think of this as a fork with only
one prong, or an array of children with length 1.

It's possible for the the size of the sequence to exceed 32 bits, the
max size for bitwise operations. When this happens, we make more room by
converting the right part of the id to a string and storing it in an
overflow variable. We use a base 32 string representation, because 32 is
the largest power of 2 that is supported by toString(). We want the base
to be large so that the resulting ids are compact, and we want the base
to be a power of 2 because every log2(base) bits corresponds to a single
character, i.e. every log2(32) = 5 bits. That means we can lop bits off
the end 5 at a time without affecting the final result.

* Incremental hydration

Stores the tree context on the dehydrated Suspense boundary's state
object so it resume where it left off.

* Add useId to react-debug-tools

* Add selective hydration test

Demonstrates that selective hydration works and ids are preserved even
after subsequent client updates.
2021-11-01 13:30:44 -07:00
Andrew ClarkandGitHub 21400bc0d7 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
Andrew ClarkandGitHub cb80bc63d5 Upgrade useSyncExternalStore to alpha channel (#22662)
* Move useSyncExternalStore shim to a nested entrypoint

Also renames `useSyncExternalStoreExtra` to
`useSyncExternalStoreWithSelector`.

- 'use-sync-external-store/shim' -> A shim for `useSyncExternalStore`
  that works in React 16 and 17 (any release that supports hooks). The
  module will first check if the built-in React API exists, before
  falling back to the shim.
- 'use-sync-external-store/with-selector' -> An extended version of
  `useSyncExternalStore` that also supports `selector` and `isEqual`
  options. It does _not_ shim `use-sync-external-store`; it composes the
  built-in React API. **Use this if you only support 18+.**
- 'use-sync-external-store/shim/with-selector' -> Same API, but it
  composes `use-sync-external-store/shim` instead. **Use this for
  compatibility with 16 and 17.**
- 'use-sync-external-store' -> Re-exports React's built-in API. Not
  meant to be used. It will warn and direct users to either the shim or
  the built-in API.

* Upgrade useSyncExternalStore to alpha channel
2021-10-31 15:38:03 -07:00