Last active
September 6, 2022 07:10
-
-
Save nvie/b540b1783a6debab836f8155a43e543b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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