Skip to content

Commit cfd8193

Browse files
authored
Add useSyncExternalStore to react-debug-tools (#22240)
Adds support for useSyncExternalStore to react-debug-tools, which in turn adds support for React Devtools. Test plan: I added a test to ReactHooksInspectionIntegration, based on existing one for useMutableSource.
1 parent 8e80592 commit cfd8193

File tree

2 files changed

+46
-1
lines changed

2 files changed

+46
-1
lines changed

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

+13-1
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,19 @@ function useSyncExternalStore<T>(
269269
subscribe: (() => void) => () => void,
270270
getSnapshot: () => T,
271271
): T {
272-
throw new Error('Not yet implemented');
272+
// useSyncExternalStore() composes multiple hooks internally.
273+
// Advance the current hook index the same number of times
274+
// so that subsequent hooks have the right memoized state.
275+
nextHook(); // SyncExternalStore
276+
nextHook(); // LayoutEffect
277+
nextHook(); // Effect
278+
const value = getSnapshot();
279+
hookLog.push({
280+
primitive: 'SyncExternalStore',
281+
stackError: new Error(),
282+
value,
283+
});
284+
return value;
273285
}
274286

275287
function useTransition(): [boolean, (() => void) => void] {

packages/react-debug-tools/src/__tests__/ReactHooksInspectionIntegration-test.js

+33
Original file line numberDiff line numberDiff line change
@@ -878,4 +878,37 @@ describe('ReactHooksInspectionIntegration', () => {
878878
},
879879
]);
880880
});
881+
882+
// @gate experimental || www
883+
it('should support composite useSyncExternalStore hook', () => {
884+
const useSyncExternalStore = React.unstable_useSyncExternalStore;
885+
function Foo() {
886+
const value = useSyncExternalStore(
887+
() => () => {},
888+
() => 'snapshot',
889+
);
890+
React.useMemo(() => 'memo', []);
891+
return value;
892+
}
893+
894+
const renderer = ReactTestRenderer.create(<Foo />);
895+
const childFiber = renderer.root.findByType(Foo)._currentFiber();
896+
const tree = ReactDebugTools.inspectHooksOfFiber(childFiber);
897+
expect(tree).toEqual([
898+
{
899+
id: 0,
900+
isStateEditable: false,
901+
name: 'SyncExternalStore',
902+
value: 'snapshot',
903+
subHooks: [],
904+
},
905+
{
906+
id: 1,
907+
isStateEditable: false,
908+
name: 'Memo',
909+
value: 'memo',
910+
subHooks: [],
911+
},
912+
]);
913+
});
881914
});

0 commit comments

Comments
 (0)