Skip to content

Instantly share code, notes, and snippets.

@nvie
Last active September 6, 2022 07:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nvie/b540b1783a6debab836f8155a43e543b to your computer and use it in GitHub Desktop.
Save nvie/b540b1783a6debab836f8155a43e543b to your computer and use it in GitHub Desktop.
import { Suspense, useEffect, useState } from "react";
import type { ReactElement } from "react";
type Props = {
fallback: ReactElement;
children: () => ReactElement;
};
/**
* Almost like a normal <Suspense> component, except that for server-side
* renders, the fallback will be used.
*
* The child props will have to be provided in a function, i.e. change:
*
* <Suspense fallback={<Loading />}>
* <MyRealComponent a={1} />
* </Suspense>
*
* To:
*
* <ClientSideSuspense fallback={<Loading />}>
* {() => <MyRealComponent a={1} />}
* </ClientSideSuspense>
*
*/
function ClientSideSuspense(props: Props): ReactElement {
const [mounted, setMounted] = useState(false);
useEffect(() => {
// Effects are never executed on the server side. The point of this is to
// delay the flipping of this boolean until after hydration has happened.
setMounted(true);
}, []);
return (
<Suspense fallback={props.fallback}>
{mounted ? props.children() : props.fallback}
</Suspense>
);
}
export default ClientSideSuspense;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment