Skip to content

Commit 8a16679

Browse files
committed
Wire up the native API for useSyncExternalStore
Adds useSyncExternalStore to the internal dispatcher, and exports the native API from the React package without yet implementing it.
1 parent 031abd2 commit 8a16679

17 files changed

+288
-35
lines changed

packages/react-debug-tools/src/ReactDebugHooks.js

+8
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,13 @@ function useMutableSource<Source, Snapshot>(
265265
return value;
266266
}
267267

268+
function useSyncExternalStore<T>(
269+
subscribe: (() => void) => () => void,
270+
getSnapshot: () => T,
271+
): T {
272+
throw new Error('Not yet implemented');
273+
}
274+
268275
function useTransition(): [boolean, (() => void) => void] {
269276
// useTransition() composes multiple hooks internally.
270277
// Advance the current hook index the same number of times
@@ -326,6 +333,7 @@ const Dispatcher: DispatcherType = {
326333
useState,
327334
useTransition,
328335
useMutableSource,
336+
useSyncExternalStore,
329337
useDeferredValue,
330338
useOpaqueIdentifier,
331339
};

packages/react-dom/src/server/ReactPartialRendererHooks.js

+8
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,13 @@ function useMutableSource<Source, Snapshot>(
462462
return getSnapshot(source._source);
463463
}
464464

465+
function useSyncExternalStore<T>(
466+
subscribe: (() => void) => () => void,
467+
getSnapshot: () => T,
468+
): T {
469+
throw new Error('Not yet implemented');
470+
}
471+
465472
function useDeferredValue<T>(value: T): T {
466473
resolveCurrentlyRenderingComponent();
467474
return value;
@@ -514,6 +521,7 @@ export const Dispatcher: DispatcherType = {
514521
useOpaqueIdentifier,
515522
// Subscriptions are not setup in a server environment.
516523
useMutableSource,
524+
useSyncExternalStore,
517525
};
518526

519527
if (enableCache) {

packages/react-reconciler/src/ReactFiberHooks.new.js

+77
Original file line numberDiff line numberDiff line change
@@ -1242,6 +1242,20 @@ function updateMutableSource<Source, Snapshot>(
12421242
return useMutableSource(hook, source, getSnapshot, subscribe);
12431243
}
12441244

1245+
function mountSyncExternalStore<T>(
1246+
subscribe: (() => void) => () => void,
1247+
getSnapshot: () => T,
1248+
): T {
1249+
throw new Error('Not yet implemented');
1250+
}
1251+
1252+
function updateSyncExternalStore<T>(
1253+
subscribe: (() => void) => () => void,
1254+
getSnapshot: () => T,
1255+
): T {
1256+
throw new Error('Not yet implemented');
1257+
}
1258+
12451259
function mountState<S>(
12461260
initialState: (() => S) | S,
12471261
): [S, Dispatch<BasicStateAction<S>>] {
@@ -2079,6 +2093,7 @@ export const ContextOnlyDispatcher: Dispatcher = {
20792093
useDeferredValue: throwInvalidHookError,
20802094
useTransition: throwInvalidHookError,
20812095
useMutableSource: throwInvalidHookError,
2096+
useSyncExternalStore: throwInvalidHookError,
20822097
useOpaqueIdentifier: throwInvalidHookError,
20832098

20842099
unstable_isNewReconciler: enableNewReconciler,
@@ -2104,6 +2119,7 @@ const HooksDispatcherOnMount: Dispatcher = {
21042119
useDeferredValue: mountDeferredValue,
21052120
useTransition: mountTransition,
21062121
useMutableSource: mountMutableSource,
2122+
useSyncExternalStore: mountSyncExternalStore,
21072123
useOpaqueIdentifier: mountOpaqueIdentifier,
21082124

21092125
unstable_isNewReconciler: enableNewReconciler,
@@ -2129,6 +2145,7 @@ const HooksDispatcherOnUpdate: Dispatcher = {
21292145
useDeferredValue: updateDeferredValue,
21302146
useTransition: updateTransition,
21312147
useMutableSource: updateMutableSource,
2148+
useSyncExternalStore: updateSyncExternalStore,
21322149
useOpaqueIdentifier: updateOpaqueIdentifier,
21332150

21342151
unstable_isNewReconciler: enableNewReconciler,
@@ -2154,6 +2171,7 @@ const HooksDispatcherOnRerender: Dispatcher = {
21542171
useDeferredValue: rerenderDeferredValue,
21552172
useTransition: rerenderTransition,
21562173
useMutableSource: updateMutableSource,
2174+
useSyncExternalStore: mountSyncExternalStore,
21572175
useOpaqueIdentifier: rerenderOpaqueIdentifier,
21582176

21592177
unstable_isNewReconciler: enableNewReconciler,
@@ -2302,6 +2320,14 @@ if (__DEV__) {
23022320
mountHookTypesDev();
23032321
return mountMutableSource(source, getSnapshot, subscribe);
23042322
},
2323+
useSyncExternalStore<T>(
2324+
subscribe: (() => void) => () => void,
2325+
getSnapshot: () => T,
2326+
): T {
2327+
currentHookNameInDev = 'useSyncExternalStore';
2328+
mountHookTypesDev();
2329+
return mountSyncExternalStore(subscribe, getSnapshot);
2330+
},
23052331
useOpaqueIdentifier(): OpaqueIDType | void {
23062332
currentHookNameInDev = 'useOpaqueIdentifier';
23072333
mountHookTypesDev();
@@ -2426,6 +2452,14 @@ if (__DEV__) {
24262452
updateHookTypesDev();
24272453
return mountMutableSource(source, getSnapshot, subscribe);
24282454
},
2455+
useSyncExternalStore<T>(
2456+
subscribe: (() => void) => () => void,
2457+
getSnapshot: () => T,
2458+
): T {
2459+
currentHookNameInDev = 'useSyncExternalStore';
2460+
updateHookTypesDev();
2461+
return mountSyncExternalStore(subscribe, getSnapshot);
2462+
},
24292463
useOpaqueIdentifier(): OpaqueIDType | void {
24302464
currentHookNameInDev = 'useOpaqueIdentifier';
24312465
updateHookTypesDev();
@@ -2550,6 +2584,14 @@ if (__DEV__) {
25502584
updateHookTypesDev();
25512585
return updateMutableSource(source, getSnapshot, subscribe);
25522586
},
2587+
useSyncExternalStore<T>(
2588+
subscribe: (() => void) => () => void,
2589+
getSnapshot: () => T,
2590+
): T {
2591+
currentHookNameInDev = 'useSyncExternalStore';
2592+
updateHookTypesDev();
2593+
return updateSyncExternalStore(subscribe, getSnapshot);
2594+
},
25532595
useOpaqueIdentifier(): OpaqueIDType | void {
25542596
currentHookNameInDev = 'useOpaqueIdentifier';
25552597
updateHookTypesDev();
@@ -2675,6 +2717,14 @@ if (__DEV__) {
26752717
updateHookTypesDev();
26762718
return updateMutableSource(source, getSnapshot, subscribe);
26772719
},
2720+
useSyncExternalStore<T>(
2721+
subscribe: (() => void) => () => void,
2722+
getSnapshot: () => T,
2723+
): T {
2724+
currentHookNameInDev = 'useSyncExternalStore';
2725+
updateHookTypesDev();
2726+
return updateSyncExternalStore(subscribe, getSnapshot);
2727+
},
26782728
useOpaqueIdentifier(): OpaqueIDType | void {
26792729
currentHookNameInDev = 'useOpaqueIdentifier';
26802730
updateHookTypesDev();
@@ -2813,6 +2863,15 @@ if (__DEV__) {
28132863
mountHookTypesDev();
28142864
return mountMutableSource(source, getSnapshot, subscribe);
28152865
},
2866+
useSyncExternalStore<T>(
2867+
subscribe: (() => void) => () => void,
2868+
getSnapshot: () => T,
2869+
): T {
2870+
currentHookNameInDev = 'useSyncExternalStore';
2871+
warnInvalidHookAccess();
2872+
mountHookTypesDev();
2873+
return mountSyncExternalStore(subscribe, getSnapshot);
2874+
},
28162875
useOpaqueIdentifier(): OpaqueIDType | void {
28172876
currentHookNameInDev = 'useOpaqueIdentifier';
28182877
warnInvalidHookAccess();
@@ -2952,6 +3011,15 @@ if (__DEV__) {
29523011
updateHookTypesDev();
29533012
return updateMutableSource(source, getSnapshot, subscribe);
29543013
},
3014+
useSyncExternalStore<T>(
3015+
subscribe: (() => void) => () => void,
3016+
getSnapshot: () => T,
3017+
): T {
3018+
currentHookNameInDev = 'useSyncExternalStore';
3019+
warnInvalidHookAccess();
3020+
updateHookTypesDev();
3021+
return updateSyncExternalStore(subscribe, getSnapshot);
3022+
},
29553023
useOpaqueIdentifier(): OpaqueIDType | void {
29563024
currentHookNameInDev = 'useOpaqueIdentifier';
29573025
warnInvalidHookAccess();
@@ -3092,6 +3160,15 @@ if (__DEV__) {
30923160
updateHookTypesDev();
30933161
return updateMutableSource(source, getSnapshot, subscribe);
30943162
},
3163+
useSyncExternalStore<T>(
3164+
subscribe: (() => void) => () => void,
3165+
getSnapshot: () => T,
3166+
): T {
3167+
currentHookNameInDev = 'useSyncExternalStore';
3168+
warnInvalidHookAccess();
3169+
updateHookTypesDev();
3170+
return updateSyncExternalStore(subscribe, getSnapshot);
3171+
},
30953172
useOpaqueIdentifier(): OpaqueIDType | void {
30963173
currentHookNameInDev = 'useOpaqueIdentifier';
30973174
warnInvalidHookAccess();

packages/react-reconciler/src/ReactFiberHooks.old.js

+77
Original file line numberDiff line numberDiff line change
@@ -1242,6 +1242,20 @@ function updateMutableSource<Source, Snapshot>(
12421242
return useMutableSource(hook, source, getSnapshot, subscribe);
12431243
}
12441244

1245+
function mountSyncExternalStore<T>(
1246+
subscribe: (() => void) => () => void,
1247+
getSnapshot: () => T,
1248+
): T {
1249+
throw new Error('Not yet implemented');
1250+
}
1251+
1252+
function updateSyncExternalStore<T>(
1253+
subscribe: (() => void) => () => void,
1254+
getSnapshot: () => T,
1255+
): T {
1256+
throw new Error('Not yet implemented');
1257+
}
1258+
12451259
function mountState<S>(
12461260
initialState: (() => S) | S,
12471261
): [S, Dispatch<BasicStateAction<S>>] {
@@ -2079,6 +2093,7 @@ export const ContextOnlyDispatcher: Dispatcher = {
20792093
useDeferredValue: throwInvalidHookError,
20802094
useTransition: throwInvalidHookError,
20812095
useMutableSource: throwInvalidHookError,
2096+
useSyncExternalStore: throwInvalidHookError,
20822097
useOpaqueIdentifier: throwInvalidHookError,
20832098

20842099
unstable_isNewReconciler: enableNewReconciler,
@@ -2104,6 +2119,7 @@ const HooksDispatcherOnMount: Dispatcher = {
21042119
useDeferredValue: mountDeferredValue,
21052120
useTransition: mountTransition,
21062121
useMutableSource: mountMutableSource,
2122+
useSyncExternalStore: mountSyncExternalStore,
21072123
useOpaqueIdentifier: mountOpaqueIdentifier,
21082124

21092125
unstable_isNewReconciler: enableNewReconciler,
@@ -2129,6 +2145,7 @@ const HooksDispatcherOnUpdate: Dispatcher = {
21292145
useDeferredValue: updateDeferredValue,
21302146
useTransition: updateTransition,
21312147
useMutableSource: updateMutableSource,
2148+
useSyncExternalStore: updateSyncExternalStore,
21322149
useOpaqueIdentifier: updateOpaqueIdentifier,
21332150

21342151
unstable_isNewReconciler: enableNewReconciler,
@@ -2154,6 +2171,7 @@ const HooksDispatcherOnRerender: Dispatcher = {
21542171
useDeferredValue: rerenderDeferredValue,
21552172
useTransition: rerenderTransition,
21562173
useMutableSource: updateMutableSource,
2174+
useSyncExternalStore: mountSyncExternalStore,
21572175
useOpaqueIdentifier: rerenderOpaqueIdentifier,
21582176

21592177
unstable_isNewReconciler: enableNewReconciler,
@@ -2302,6 +2320,14 @@ if (__DEV__) {
23022320
mountHookTypesDev();
23032321
return mountMutableSource(source, getSnapshot, subscribe);
23042322
},
2323+
useSyncExternalStore<T>(
2324+
subscribe: (() => void) => () => void,
2325+
getSnapshot: () => T,
2326+
): T {
2327+
currentHookNameInDev = 'useSyncExternalStore';
2328+
mountHookTypesDev();
2329+
return mountSyncExternalStore(subscribe, getSnapshot);
2330+
},
23052331
useOpaqueIdentifier(): OpaqueIDType | void {
23062332
currentHookNameInDev = 'useOpaqueIdentifier';
23072333
mountHookTypesDev();
@@ -2426,6 +2452,14 @@ if (__DEV__) {
24262452
updateHookTypesDev();
24272453
return mountMutableSource(source, getSnapshot, subscribe);
24282454
},
2455+
useSyncExternalStore<T>(
2456+
subscribe: (() => void) => () => void,
2457+
getSnapshot: () => T,
2458+
): T {
2459+
currentHookNameInDev = 'useSyncExternalStore';
2460+
updateHookTypesDev();
2461+
return mountSyncExternalStore(subscribe, getSnapshot);
2462+
},
24292463
useOpaqueIdentifier(): OpaqueIDType | void {
24302464
currentHookNameInDev = 'useOpaqueIdentifier';
24312465
updateHookTypesDev();
@@ -2550,6 +2584,14 @@ if (__DEV__) {
25502584
updateHookTypesDev();
25512585
return updateMutableSource(source, getSnapshot, subscribe);
25522586
},
2587+
useSyncExternalStore<T>(
2588+
subscribe: (() => void) => () => void,
2589+
getSnapshot: () => T,
2590+
): T {
2591+
currentHookNameInDev = 'useSyncExternalStore';
2592+
updateHookTypesDev();
2593+
return updateSyncExternalStore(subscribe, getSnapshot);
2594+
},
25532595
useOpaqueIdentifier(): OpaqueIDType | void {
25542596
currentHookNameInDev = 'useOpaqueIdentifier';
25552597
updateHookTypesDev();
@@ -2675,6 +2717,14 @@ if (__DEV__) {
26752717
updateHookTypesDev();
26762718
return updateMutableSource(source, getSnapshot, subscribe);
26772719
},
2720+
useSyncExternalStore<T>(
2721+
subscribe: (() => void) => () => void,
2722+
getSnapshot: () => T,
2723+
): T {
2724+
currentHookNameInDev = 'useSyncExternalStore';
2725+
updateHookTypesDev();
2726+
return updateSyncExternalStore(subscribe, getSnapshot);
2727+
},
26782728
useOpaqueIdentifier(): OpaqueIDType | void {
26792729
currentHookNameInDev = 'useOpaqueIdentifier';
26802730
updateHookTypesDev();
@@ -2813,6 +2863,15 @@ if (__DEV__) {
28132863
mountHookTypesDev();
28142864
return mountMutableSource(source, getSnapshot, subscribe);
28152865
},
2866+
useSyncExternalStore<T>(
2867+
subscribe: (() => void) => () => void,
2868+
getSnapshot: () => T,
2869+
): T {
2870+
currentHookNameInDev = 'useSyncExternalStore';
2871+
warnInvalidHookAccess();
2872+
mountHookTypesDev();
2873+
return mountSyncExternalStore(subscribe, getSnapshot);
2874+
},
28162875
useOpaqueIdentifier(): OpaqueIDType | void {
28172876
currentHookNameInDev = 'useOpaqueIdentifier';
28182877
warnInvalidHookAccess();
@@ -2952,6 +3011,15 @@ if (__DEV__) {
29523011
updateHookTypesDev();
29533012
return updateMutableSource(source, getSnapshot, subscribe);
29543013
},
3014+
useSyncExternalStore<T>(
3015+
subscribe: (() => void) => () => void,
3016+
getSnapshot: () => T,
3017+
): T {
3018+
currentHookNameInDev = 'useSyncExternalStore';
3019+
warnInvalidHookAccess();
3020+
updateHookTypesDev();
3021+
return updateSyncExternalStore(subscribe, getSnapshot);
3022+
},
29553023
useOpaqueIdentifier(): OpaqueIDType | void {
29563024
currentHookNameInDev = 'useOpaqueIdentifier';
29573025
warnInvalidHookAccess();
@@ -3092,6 +3160,15 @@ if (__DEV__) {
30923160
updateHookTypesDev();
30933161
return updateMutableSource(source, getSnapshot, subscribe);
30943162
},
3163+
useSyncExternalStore<T>(
3164+
subscribe: (() => void) => () => void,
3165+
getSnapshot: () => T,
3166+
): T {
3167+
currentHookNameInDev = 'useSyncExternalStore';
3168+
warnInvalidHookAccess();
3169+
updateHookTypesDev();
3170+
return updateSyncExternalStore(subscribe, getSnapshot);
3171+
},
30953172
useOpaqueIdentifier(): OpaqueIDType | void {
30963173
currentHookNameInDev = 'useOpaqueIdentifier';
30973174
warnInvalidHookAccess();

packages/react-reconciler/src/ReactInternalTypes.js

+5
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ export type HookType =
4141
| 'useDeferredValue'
4242
| 'useTransition'
4343
| 'useMutableSource'
44+
| 'useSyncExternalStore'
4445
| 'useOpaqueIdentifier'
4546
| 'useCacheRefresh';
4647

@@ -304,6 +305,10 @@ export type Dispatcher = {|
304305
getSnapshot: MutableSourceGetSnapshotFn<Source, Snapshot>,
305306
subscribe: MutableSourceSubscribeFn<Source, Snapshot>,
306307
): Snapshot,
308+
useSyncExternalStore<T>(
309+
subscribe: (() => void) => () => void,
310+
getSnapshot: () => T,
311+
): T,
307312
useOpaqueIdentifier(): any,
308313
useCacheRefresh?: () => <T>(?() => T, ?T) => void,
309314

0 commit comments

Comments
 (0)