Concurrent rendering can render the same component twice with different store values, which produces a torn UI unless the store tells React how to subscribe.
const width = useSyncExternalStore(
(cb) => { window.addEventListener('resize', cb)
return () => window.removeEventListener('resize', cb) },
() => window.innerWidth, // client snapshot
() => 1024, // server snapshot
)
// the getSnapshot must return a CACHED value: returning a
// new object each call is an infinite render loop.
The infinite loop from returning a fresh object is the mistake everybody makes once, and the error message says the snapshot changed rather than explaining why. Most application code never calls this directly — it exists so that a store library can be correct under concurrent rendering, which is why every one of them released a version in the weeks after 18 shipped.