From 3982cfe37165e31b9eeb9568d0e9f832b2caa638 Mon Sep 17 00:00:00 2001 From: Andrew Clark Date: Sun, 31 Oct 2021 16:58:15 -0400 Subject: [PATCH] Upgrade useSyncExternalStore to alpha channel --- ReactVersions.js | 2 +- .../ReactHooksInspectionIntegration-test.js | 3 +-- .../src/__tests__/ReactDOMFizzServer-test.js | 6 +---- .../__tests__/useSyncExternalStore-test.js | 3 +-- packages/react/index.classic.fb.js | 1 - packages/react/index.experimental.js | 2 +- packages/react/index.js | 1 - packages/react/index.modern.fb.js | 1 - packages/react/index.stable.js | 1 + .../useSyncExternalStoreNative-test.js | 27 ++++--------------- .../useSyncExternalStoreShared-test.js | 12 ++++----- .../useSyncExternalStoreShimServer-test.js | 2 -- ...seSyncExternalStore.forward-to-built-in.js | 2 +- .../src/useSyncExternalStoreShim.js | 2 +- scripts/jest/TestFlags.js | 5 ++-- 15 files changed, 20 insertions(+), 50 deletions(-) diff --git a/ReactVersions.js b/ReactVersions.js index 2ce7680f0191cd..bdab35424e8856 100644 --- a/ReactVersions.js +++ b/ReactVersions.js @@ -36,6 +36,7 @@ const stablePackages = { 'react-refresh': '0.11.0', 'react-test-renderer': ReactVersion, 'use-subscription': '1.6.0', + 'use-sync-external-store': '1.0.0', scheduler: '0.21.0', }; @@ -47,7 +48,6 @@ const experimentalPackages = [ 'react-fs', 'react-pg', 'react-server-dom-webpack', - 'use-sync-external-store', ]; module.exports = { diff --git a/packages/react-debug-tools/src/__tests__/ReactHooksInspectionIntegration-test.js b/packages/react-debug-tools/src/__tests__/ReactHooksInspectionIntegration-test.js index 6937efd6315722..087d74d6287245 100644 --- a/packages/react-debug-tools/src/__tests__/ReactHooksInspectionIntegration-test.js +++ b/packages/react-debug-tools/src/__tests__/ReactHooksInspectionIntegration-test.js @@ -1055,9 +1055,8 @@ describe('ReactHooksInspectionIntegration', () => { ]); }); - // @gate experimental || www it('should support composite useSyncExternalStore hook', () => { - const useSyncExternalStore = React.unstable_useSyncExternalStore; + const useSyncExternalStore = React.useSyncExternalStore; function Foo() { const value = useSyncExternalStore( () => () => {}, diff --git a/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js b/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js index f6a5c48166874c..abbbdc15787535 100644 --- a/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js +++ b/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js @@ -56,7 +56,7 @@ describe('ReactDOMFizzServer', () => { jest.requireActual('react'), ); } - useSyncExternalStore = React.unstable_useSyncExternalStore; + useSyncExternalStore = React.useSyncExternalStore; useSyncExternalStoreWithSelector = require('use-sync-external-store/with-selector') .useSyncExternalStoreWithSelector; @@ -1675,7 +1675,6 @@ describe('ReactDOMFizzServer', () => { ); }); - // @gate supportsNativeUseSyncExternalStore // @gate experimental it('calls getServerSnapshot instead of getSnapshot', async () => { const ref = React.createRef(); @@ -1746,7 +1745,6 @@ describe('ReactDOMFizzServer', () => { // The selector implementation uses the lazy ref initialization pattern // @gate !(enableUseRefAccessWarning && __DEV__) - // @gate supportsNativeUseSyncExternalStore // @gate experimental it('calls getServerSnapshot instead of getSnapshot (with selector and isEqual)', async () => { // Same as previous test, but with a selector that returns a complex object @@ -1827,7 +1825,6 @@ describe('ReactDOMFizzServer', () => { expect(ref.current).toEqual(serverRenderedDiv); }); - // @gate supportsNativeUseSyncExternalStore // @gate experimental it( 'errors during hydration force a client render at the nearest Suspense ' + @@ -1976,7 +1973,6 @@ describe('ReactDOMFizzServer', () => { }, ); - // @gate supportsNativeUseSyncExternalStore // @gate experimental it( 'errors during hydration force a client render at the nearest Suspense ' + diff --git a/packages/react-reconciler/src/__tests__/useSyncExternalStore-test.js b/packages/react-reconciler/src/__tests__/useSyncExternalStore-test.js index d939a02bee897f..623ea127559071 100644 --- a/packages/react-reconciler/src/__tests__/useSyncExternalStore-test.js +++ b/packages/react-reconciler/src/__tests__/useSyncExternalStore-test.js @@ -36,7 +36,7 @@ describe('useSyncExternalStore', () => { useImperativeHandle = React.useImperativeHandle; forwardRef = React.forwardRef; useRef = React.useRef; - useSyncExternalStore = React.unstable_useSyncExternalStore; + useSyncExternalStore = React.useSyncExternalStore; startTransition = React.startTransition; act = require('jest-react').act; @@ -70,7 +70,6 @@ describe('useSyncExternalStore', () => { }; } - // @gate supportsNativeUseSyncExternalStore test( 'detects interleaved mutations during a concurrent read before ' + 'layout effects fire', diff --git a/packages/react/index.classic.fb.js b/packages/react/index.classic.fb.js index 568a8ada613d93..c5854f8f6d398d 100644 --- a/packages/react/index.classic.fb.js +++ b/packages/react/index.classic.fb.js @@ -54,7 +54,6 @@ export { useMutableSource, useMutableSource as unstable_useMutableSource, useSyncExternalStore, - useSyncExternalStore as unstable_useSyncExternalStore, useReducer, useRef, useState, diff --git a/packages/react/index.experimental.js b/packages/react/index.experimental.js index 7491bbb7e832d9..4b4fa89e018989 100644 --- a/packages/react/index.experimental.js +++ b/packages/react/index.experimental.js @@ -47,7 +47,7 @@ export { useLayoutEffect, useMemo, useMutableSource as unstable_useMutableSource, - useSyncExternalStore as unstable_useSyncExternalStore, + useSyncExternalStore, useReducer, useRef, useState, diff --git a/packages/react/index.js b/packages/react/index.js index 59cc05f0254e68..9a6a99ee52189e 100644 --- a/packages/react/index.js +++ b/packages/react/index.js @@ -73,7 +73,6 @@ export { useMemo, useMutableSource, useSyncExternalStore, - useSyncExternalStore as unstable_useSyncExternalStore, useReducer, useRef, useState, diff --git a/packages/react/index.modern.fb.js b/packages/react/index.modern.fb.js index cd60ee426fa650..8d08a43b909467 100644 --- a/packages/react/index.modern.fb.js +++ b/packages/react/index.modern.fb.js @@ -53,7 +53,6 @@ export { useMutableSource, useMutableSource as unstable_useMutableSource, useSyncExternalStore, - useSyncExternalStore as unstable_useSyncExternalStore, useReducer, useRef, useState, diff --git a/packages/react/index.stable.js b/packages/react/index.stable.js index 4e4682b8fc29f9..3a0600d11a713b 100644 --- a/packages/react/index.stable.js +++ b/packages/react/index.stable.js @@ -40,6 +40,7 @@ export { useLayoutEffect, useMemo, useMutableSource as unstable_useMutableSource, + useSyncExternalStore, useReducer, useRef, useState, diff --git a/packages/use-sync-external-store/src/__tests__/useSyncExternalStoreNative-test.js b/packages/use-sync-external-store/src/__tests__/useSyncExternalStoreNative-test.js index 379b5d051c3b49..caedd74f744708 100644 --- a/packages/use-sync-external-store/src/__tests__/useSyncExternalStoreNative-test.js +++ b/packages/use-sync-external-store/src/__tests__/useSyncExternalStoreNative-test.js @@ -36,8 +36,6 @@ describe('useSyncExternalStore (userspace shim, server rendering)', () => { startTransition: _, // eslint-disable-next-line no-unused-vars useSyncExternalStore: __, - // eslint-disable-next-line no-unused-vars - unstable_useSyncExternalStore: ___, ...otherExports } = jest.requireActual('react'); return otherExports; @@ -62,6 +60,11 @@ describe('useSyncExternalStore (userspace shim, server rendering)', () => { jest.mock('use-sync-external-store/src/useSyncExternalStore', () => jest.requireActual('use-sync-external-store/shim'), ); + jest.mock('use-sync-external-store/src/isServerEnvironment', () => + jest.requireActual( + 'use-sync-external-store/src/forks/isServerEnvironment.native', + ), + ); } useSyncExternalStore = require('use-sync-external-store/shim') .useSyncExternalStore; @@ -117,26 +120,6 @@ describe('useSyncExternalStore (userspace shim, server rendering)', () => { expect(root).toMatchRenderedOutput('client'); }); - test('native version', async () => { - const store = createExternalStore('client'); - - function App() { - const text = useSyncExternalStore( - store.subscribe, - store.getState, - () => 'server', - ); - return ; - } - - const root = ReactNoop.createRoot(); - await act(() => { - root.render(); - }); - expect(Scheduler).toHaveYielded(['client']); - expect(root).toMatchRenderedOutput('client'); - }); - // @gate !(enableUseRefAccessWarning && __DEV__) test('Using isEqual to bailout', async () => { const store = createExternalStore({a: 0, b: 0}); diff --git a/packages/use-sync-external-store/src/__tests__/useSyncExternalStoreShared-test.js b/packages/use-sync-external-store/src/__tests__/useSyncExternalStoreShared-test.js index 817ca3781bd3dc..5af9e9767ab0cc 100644 --- a/packages/use-sync-external-store/src/__tests__/useSyncExternalStoreShared-test.js +++ b/packages/use-sync-external-store/src/__tests__/useSyncExternalStoreShared-test.js @@ -25,7 +25,7 @@ describe('Shared useSyncExternalStore behavior (shim and built-in)', () => { beforeEach(() => { jest.resetModules(); - if (!gate(flags => flags.supportsNativeUseSyncExternalStore)) { + if (gate(flags => flags.enableUseSyncExternalStoreShim)) { // Remove useSyncExternalStore from the React imports so that we use the // shim instead. Also removing startTransition, since we use that to // detect outdated 18 alphas that don't yet include useSyncExternalStore. @@ -38,8 +38,6 @@ describe('Shared useSyncExternalStore behavior (shim and built-in)', () => { startTransition: _, // eslint-disable-next-line no-unused-vars useSyncExternalStore: __, - // eslint-disable-next-line no-unused-vars - unstable_useSyncExternalStore: ___, ...otherExports } = jest.requireActual('react'); return otherExports; @@ -85,7 +83,7 @@ describe('Shared useSyncExternalStore behavior (shim and built-in)', () => { function createRoot(container) { // This wrapper function exists so we can test both legacy roots and // concurrent roots. - if (gate(flags => flags.supportsNativeUseSyncExternalStore)) { + if (gate(flags => !flags.enableUseSyncExternalStoreShim)) { // The native implementation only exists in 18+, so we test using // concurrent mode. To test the legacy root behavior in the native // implementation (which is supported in the sense that it needs to have @@ -272,7 +270,7 @@ describe('Shared useSyncExternalStore behavior (shim and built-in)', () => { // In React 18, you can't observe in between a sync render and its // passive effects, so this is only relevant to legacy roots - // @gate !supportsNativeUseSyncExternalStore + // @gate enableUseSyncExternalStoreShim test( "compares to current state before bailing out, even when there's a " + 'mutation in between the sync and passive effects', @@ -554,7 +552,7 @@ describe('Shared useSyncExternalStore behavior (shim and built-in)', () => { await act(() => { store.set({value: 1, throwInGetSnapshot: true, throwInIsEqual: false}); }); - if (gate(flags => flags.supportsNativeUseSyncExternalStore)) { + if (gate(flags => !flags.enableUseSyncExternalStoreShim)) { expect(Scheduler).toHaveYielded([ 'Error in getSnapshot', // In a concurrent root, React renders a second time to attempt to @@ -718,7 +716,7 @@ describe('Shared useSyncExternalStore behavior (shim and built-in)', () => { container.innerHTML = '
server
'; const serverRenderedDiv = container.getElementsByTagName('div')[0]; - if (gate(flags => flags.supportsNativeUseSyncExternalStore)) { + if (gate(flags => !flags.enableUseSyncExternalStoreShim)) { act(() => { ReactDOM.hydrateRoot(container, ); }); diff --git a/packages/use-sync-external-store/src/__tests__/useSyncExternalStoreShimServer-test.js b/packages/use-sync-external-store/src/__tests__/useSyncExternalStoreShimServer-test.js index 9023322c9f638f..016240a4d3f2f4 100644 --- a/packages/use-sync-external-store/src/__tests__/useSyncExternalStoreShimServer-test.js +++ b/packages/use-sync-external-store/src/__tests__/useSyncExternalStoreShimServer-test.js @@ -35,8 +35,6 @@ describe('useSyncExternalStore (userspace shim, server rendering)', () => { startTransition: _, // eslint-disable-next-line no-unused-vars useSyncExternalStore: __, - // eslint-disable-next-line no-unused-vars - unstable_useSyncExternalStore: ___, ...otherExports } = jest.requireActual('react'); return otherExports; diff --git a/packages/use-sync-external-store/src/forks/useSyncExternalStore.forward-to-built-in.js b/packages/use-sync-external-store/src/forks/useSyncExternalStore.forward-to-built-in.js index 307146bfd9d2da..049f0c887e2783 100644 --- a/packages/use-sync-external-store/src/forks/useSyncExternalStore.forward-to-built-in.js +++ b/packages/use-sync-external-store/src/forks/useSyncExternalStore.forward-to-built-in.js @@ -13,4 +13,4 @@ // dispatch for CommonJS interop named imports. import * as React from 'react'; -export const useSyncExternalStore = React.unstable_useSyncExternalStore; +export const useSyncExternalStore = React.useSyncExternalStore; diff --git a/packages/use-sync-external-store/src/useSyncExternalStoreShim.js b/packages/use-sync-external-store/src/useSyncExternalStoreShim.js index 5ca1c93817b882..82d944de1dd1d1 100644 --- a/packages/use-sync-external-store/src/useSyncExternalStoreShim.js +++ b/packages/use-sync-external-store/src/useSyncExternalStoreShim.js @@ -10,7 +10,7 @@ import {useSyncExternalStore as client} from './useSyncExternalStoreShimClient'; import {useSyncExternalStore as server} from './useSyncExternalStoreShimServer'; import {isServerEnvironment} from './isServerEnvironment'; -import {unstable_useSyncExternalStore as builtInAPI} from 'react'; +import {useSyncExternalStore as builtInAPI} from 'react'; const shim = isServerEnvironment ? server : client; diff --git a/scripts/jest/TestFlags.js b/scripts/jest/TestFlags.js index c1bd03e00b1a9a..af83baf0f3ec91 100644 --- a/scripts/jest/TestFlags.js +++ b/scripts/jest/TestFlags.js @@ -84,9 +84,8 @@ function getTestFlags() { source: !process.env.IS_BUILD, www, - // This isn't a flag, just a useful alias for tests. Remove once - // useSyncExternalStore lands in the `next` channel. - supportsNativeUseSyncExternalStore: __EXPERIMENTAL__ || www, + // This isn't a flag, just a useful alias for tests. + enableUseSyncExternalStoreShim: !__VARIANT__, // If there's a naming conflict between scheduler and React feature flags, the // React ones take precedence.