-
Notifications
You must be signed in to change notification settings - Fork 50.4k
Open
Labels
Status: UnconfirmedA potential issue that we haven't yet confirmed as a bugA potential issue that we haven't yet confirmed as a bug
Description
in useSyncExternalStore, subscribe is called as a passive effect, so it's possible the store value has changed between render and effect. As a solution, I can see react calls getSnapshot right after subscribing to store, to check if value is stale.
However, when using Suspense in StrictMode, getSnapshot is not called after subscribing to store
React version: 19.2.3
Steps To Reproduce
Consider below code (codesandbox)
const subscribe = (onStoreChange: () => void) => {
console.log("subscribe called");
return () => {
console.log("unsubscribe called");
};
};
const getSnapshost = () => {
console.log("getSnapshot called");
return 1;
};
const Content = ({ promise }: { promise: Promise<any> }) => {
React.use(promise);
const value = React.useSyncExternalStore(subscribe, getSnapshost);
console.log("rendered with value", value);
return <div>Value {value}</div>;
};
export default function App() {
const [, reRender] = React.useReducer((state: number) => state + 1, 0);
const promise = React.useRef(Promise.resolve());
return (
<div>
<button
onClick={() => {
console.log("button clicked");
promise.current = new Promise<void>((resolve) => {
setTimeout(() => {
resolve();
}, 500);
});
reRender();
}}
>
Trigger Suspense
</button>
<Suspense fallback={<p>Loading...</p>}>
<Content promise={promise.current} />
</Suspense>
</div>
);
}The current behavior
In StrictMode, after I click the button to trigger suspense, when it's resolved, it will re-mount the Content component, unsubscribe store, subscribe store, without calling getSnapshot again
my console is
button clicked
getSnapshot called
getSnapshot called
rendered with value 1
getSnapshot called
getSnapshot called
rendered with value 1
unsubscribe called
subscribe called
The expected behavior
The expected behavior is that getSnapshot should be always called after subscribe is called, i.e. in console I should see
subscribe called
getSnapshot called <-- after last subscribe
haskellcamargo, uroojayub-canva and imjordanxd
Metadata
Metadata
Assignees
Labels
Status: UnconfirmedA potential issue that we haven't yet confirmed as a bugA potential issue that we haven't yet confirmed as a bug