Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,9 @@ describe('useSyncExternalStore (userspace shim, server rendering)', () => {
}

const html = ReactDOMServer.renderToString(<App />);
expect(Scheduler).toHaveYielded(['server']);
expect(html).toEqual('server');

// We don't call getServerSnapshot in the shim
expect(Scheduler).toHaveYielded(['client']);
expect(html).toEqual('client');
});
});
10 changes: 9 additions & 1 deletion packages/use-sync-external-store/src/useSyncExternalStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,13 @@
import {canUseDOM} from 'shared/ExecutionEnvironment';
import {useSyncExternalStore as client} from './useSyncExternalStoreClient';
import {useSyncExternalStore as server} from './useSyncExternalStoreServer';
import * as React from 'react';

export const useSyncExternalStore = canUseDOM ? client : server;
const {unstable_useSyncExternalStore: builtInAPI} = React;

export const useSyncExternalStore =
builtInAPI !== undefined
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can delete this check from useSyncExternalStoreClient now

? ((builtInAPI: any): typeof client)
: canUseDOM
? client
: server;
19 changes: 2 additions & 17 deletions packages/use-sync-external-store/src/useSyncExternalStoreClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,7 @@ import is from 'shared/objectIs';

// Intentionally not using named imports because Rollup uses dynamic
// dispatch for CommonJS interop named imports.
const {
useState,
useEffect,
useLayoutEffect,
useDebugValue,
// The built-in API is still prefixed.
unstable_useSyncExternalStore: builtInAPI,
} = React;

// Prefer the built-in API, if it exists. If it doesn't exist, then we assume
// we're in version 16 or 17, so rendering is always synchronous. The shim
// does not support concurrent rendering, only the built-in API.
export const useSyncExternalStore =
builtInAPI !== undefined
? ((builtInAPI: any): typeof useSyncExternalStore_client)
: useSyncExternalStore_client;
const {useState, useEffect, useLayoutEffect, useDebugValue} = React;

let didWarnOld18Alpha = false;
let didWarnUncachedGetSnapshot = false;
Expand All @@ -42,7 +27,7 @@ let didWarnUncachedGetSnapshot = false;
//
// Do not assume that the clever hacks used by this hook also work in general.
// The point of this shim is to replace the need for hacks by other libraries.
function useSyncExternalStore_client<T>(
export function useSyncExternalStore<T>(
subscribe: (() => void) => () => void,
getSnapshot: () => T,
// Note: The client shim does not use getServerSnapshot, because pre-18
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,10 @@
* @flow
*/

import invariant from 'shared/invariant';

export function useSyncExternalStore<T>(
subscribe: (() => void) => () => void,
getSnapshot: () => T,
getServerSnapshot?: () => T,
): T {
if (getServerSnapshot === undefined) {
invariant(
false,
'Missing getServerSnapshot, which is required for server-' +
'rendered content.',
);
}
return getServerSnapshot();
return getSnapshot();
}