Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix hydration of components inside <Suspense> #2663

Merged
merged 7 commits into from
Aug 10, 2023

Conversation

thecrypticace
Copy link
Contributor

This is a redo of #2633 but with a more targeted fix for just React 18+

Previously, when dealing with SSR, we had a hook that would basically force a re-render of all components on page load. This also used some global state so we didn't unnecessarily cause re-renders for components that were mounting after the page had already loaded.

However, because <Suspense> delays hydration this is no longer a viable solution. I've implemented a targeted fix by (mis)using the useSyncExternalStore API. You can provide a getServerSnapshot callback that only runs on the server AND in the browser but only when hydrating. This gives us just enough info to know when hydration is happening.

I've slotted that into our useServerHandoffComplete() hook to handle the <Suspense> case. I'm also using wildcard imports, a "useSyncExternalStore" in React guard, and a lazy closure to ensure that bundlers don't statically analyze this in a way that errors for React < 18.

Fixes #2400

@vercel
Copy link

vercel bot commented Aug 9, 2023

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
headlessui-react ✅ Ready (Inspect) Visit Preview 💬 Add feedback Aug 10, 2023 2:13pm
headlessui-vue ✅ Ready (Inspect) Visit Preview 💬 Add feedback Aug 10, 2023 2:13pm

Copy link
Member

@RobinMalfait RobinMalfait left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apart from a few comments this is looking great.

Was testing it with the Dialogs and Transition components as well because we had some issues with those last time we were solving this. But this all seems to work as expected now.

Nice!

@thecrypticace thecrypticace merged commit a317866 into main Aug 10, 2023
5 checks passed
@thecrypticace thecrypticace deleted the fix/react-18-suspense branch August 10, 2023 14:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Transition issue with React Suspense
2 participants