The uncached snapshot bug
React compares snapshots with Object.is. A new object is never equal to the last one, so React keeps re-rendering until it gives up. Fix: return user; and replace user with a new object only when it changes.
useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot?) reads a value that lives outside React (a browser API or a store library) and re-renders when it changes, without the tearing bugs that a hand-made effect-and-state subscription can have.
Change the code and press Run (Ctrl+Enter). Predict what will happen first, then break it on purpose and read what changes. Your edits are saved and match the lesson page.
Ready for more? This phase has 6 hands-on exercises with automatic checks.
Practice questions
Write the code in the editor, run it, then open the model answer to compare.
Write useWindowWidth() with useSyncExternalStore, subscribing to resize, with a server snapshot of 1024.
Write usePageVisible() that returns true while the tab is visible, using document.visibilityState and the visibilitychange event.
Add a useCounterStore() hook to a createStore({ count: 0 }) store and render two <Count /> components plus a button that increments from outside React.
Explain it without notes
What do subscribe and getSnapshot each do, and when does React call them?
What is tearing, why could it happen in React 18, and how does useSyncExternalStore prevent it?
Why must the snapshot be cached, and what happens if it isn't?
When do you need getServerSnapshot, and what should it return?
Preview
Console
Nothing logged yet.Expected console output
The result of getSnapshot should be cached to avoid an infinite loop
Uncaught Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.
An error occurred in the <Profile> component.
Consider adding an error boundary to your tree to customize error handling behavior.
Visit https://react.dev/link/error-boundaries to learn more about error boundaries.