Bug: `startTransition` not working with `useSyncExternalStore`
See original GitHub issueSSR content shows a fallback during hydration if there has been an update to an external state, even if wrapped with startTransition
.
React version: 18.2.0
Steps To Reproduce
- Create a basic SSRed React application that would have suspensible content.
- Create an external store and read its values using
useSyncExternalStore
in the same component which has suspensible content. - Update this external store on the application mount(while hydrating), and wrap this update with
startTransition
;
Link to code example: https://codesandbox.io/s/react-18-starttransition-not-working-with-usesyncexternalstore-4pxygp
The current behavior
The content shows a fallback while the update is done.
The expected behavior
The content should not show a fallback, but rather update without showing it.
Issue Analytics
- State:
- Created a year ago
- Comments:12 (5 by maintainers)
Top Results From Across the Web
useSyncExternalStore - React Docs
Troubleshooting · I'm getting an error: “The result of getSnapshot should be cached” · My subscribe function gets called after every re-render.
Read more >React 18 is out! - Meteor forums
We are now encountering a problem wherein a page is being redirected to another page in SSR. This happens when the app is...
Read more >React 18 : Concurrency, Automatic Batching, Transitions ...
The problem with asynchronous transactions is once you initiate an ... With React 18, developers can use start transition API inside an ...
Read more >React 18 for External Store Libraries - YouTube
An error occurred while retrieving sharing information. Please try again later. 0:00. 0:00 / 19:22• Live. •. •. Scroll for details ...
Read more >React 18, React Redux 8, and TypeScript: What you need to ...
This is where the startTransition API comes in. ... LogRocket tells you the most impactful bugs and UX issues actually impacting users in ......
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
@stanislav-halyn hi!
I recently met a similar problem, and found answer here - https://github.com/facebook/react/issues/24476#issuecomment-1127800350
In this example, you don’t pass props from user store to suspended component directly. So, just memoize this suspended block:
Note there’s also another option, which is to not SSR LazyContent either. I.e. you can always emit fallback on the server. Then it won’t be in HTML (which is unfortunate), but you’ll also avoid this problem. If you decide to go that route, you need to throw an Error on the server only from inside the part you want to make client-only (like this lazy content). When you throw an Error on the server, with streaming SSR, the error won’t fail the render. Instead, the server will emit the Suspense fallback. The client will retry rendering when the code loads. During retry, you won’t throw, so lazy content will be able to show up. The error will be reported in the console, but you can pass
onRecoverableError
withhydrateRoot
options, detect your custom Error (e.g. by its message) and silence it because it’s expected. This is a supported way to render client-only content.