/** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @flow */ import * as React from 'react'; const {useState, useEffect, useSyncExternalStore} = React; // Create a simple external store for demonstratio function createStore(initialValue: T): { subscribe: (cb: () => void) => () => any, getSnapshot: () => T, setValue: (newValue: T) => void, } { let value = initialValue; const subscribers = new Set<() => void>(); return { subscribe(callback) { subscribers.add(callback); return () => subscribers.delete(callback); }, getSnapshot() { return value; }, setValue(newValue) { value = newValue; subscribers.forEach(callback => callback()); }, }; } const counterStore = createStore(0); const themeStore = createStore('light'); export default function UseSyncExternalStore(): React.Node { return ( <>

useSyncExternalStore()

); } function SingleHookCase(): React.Node { const count = useSyncExternalStore( counterStore.subscribe, counterStore.getSnapshot, ); return (

Single hook case

Count: {count}

); } function useCounter() { const count = useSyncExternalStore( counterStore.subscribe, counterStore.getSnapshot, ); const [localState, setLocalState] = useState(0); useEffect(() => { // Some effect }, [count]); return {count, localState, setLocalState}; } function HookTreeCase(): React.Node { const {count, localState, setLocalState} = useCounter(); return (

Hook tree case

External count: {count}

Local state: {localState}

); } function useTheme() { const theme = useSyncExternalStore( themeStore.subscribe, themeStore.getSnapshot, ); return theme; } function MultipleStoresCase() { const count = useSyncExternalStore( counterStore.subscribe, counterStore.getSnapshot, ); const theme = useTheme(); return (

Multiple stores case

Count: {count}

Theme: {theme}

); }