Created
November 23, 2019 16:19
-
-
Save tayloraleach/915ab0128dd5833237b720b7610c44cd to your computer and use it in GitHub Desktop.
React.js two-pass SSR rendering of 3rd party component (Next.js)
This file contains hidden or 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 React, { useState, useEffect } from "react"; | |
const ClientSideOnlyRenderer = props => { | |
const { initialSsrDone = false, renderDone, renderLoading } = props; | |
const [ssrDone, setSsrDone] = useState(initialSsrDone); | |
useEffect(() => setSsrDone(true), []); | |
return ssrDone ? renderDone() : renderLoading(); | |
}; | |
export default React.memo(ClientSideOnlyRenderer); |
This file contains hidden or 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 React from "react"; | |
import Layout from "../components/Layout"; | |
import ThirdPartyComponent from "../components/ThirdPartyComponent"; | |
import ClientSideOnlyRenderer from "../components/ClientSideOnlyRender"; | |
class Home extends React.Component { | |
static async getInitialProps({ req }) { | |
return { | |
isServer: !!req | |
}; | |
} | |
renderDone() { | |
return <ThirdPartyComponent />; | |
} | |
renderLoading() { | |
return <div>Loading...</div>; | |
} | |
render() { | |
const { isServer } = this.props; | |
return ( | |
<Layout> | |
<ClientSideOnlyRenderer | |
initialSsrDone={!isServer} | |
renderDone={this.renderDone} | |
renderLoading={this.renderLoading} | |
/> | |
</Layout> | |
); | |
} | |
} | |
export default Home; |
This file contains hidden or 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 React from "react"; | |
export default function Layout({ children }) { | |
return ( | |
<div> | |
{console.log("Layout rendered")} | |
NavBar here | |
<div>Header</div> | |
{children} | |
<div>Footer</div> | |
</div> | |
); | |
} |
This file contains hidden or 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 React from "react"; | |
export default function ThirdPartyComponent() { | |
console.log("3rd party component rendered"); | |
return <div>3rd Party Component</div>; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I needed this for one of my pages since I was using a component on my page that was utilizing the WEB API and calling methods on
window
which obviously can't happen on the server. This approach prevents the entire<Layout>
from re-rendering twice and allows the<ThirdPartyComponent>
to only render on the client.