1
0
Fork 0
mirror of https://github.com/terribleplan/next.js.git synced 2024-01-19 02:48:18 +00:00

Apollo example: avoid double render in browser (#4734)

Apollo's getDataFromTree is supposed to be called during the server side rendering.
Being called in browser it fires an unnecessary fake render process and blocks components from rendering with loading=true.

Also there was a mistake in this code:

    // `getDataFromTree` renders the component first, the client is passed off as a property.
    // After that rendering is done using Next's normal rendering pipeline
    this.apolloClient = props.apolloClient || initApollo(props.apolloState.data)

**Apollo** component is not rendered by getDataFromTree actually, it renders the **App** directly, thus props.apolloClient will always be undefined.

This example was discussed here: https://github.com/zeit/next.js/issues/387.
This commit is contained in:
NikitaVlaznev 2018-07-05 21:49:23 +03:00 committed by Tim Neutkens
parent 498f37e33f
commit 728871b005

View file

@ -18,32 +18,34 @@ export default (App) => {
// Run all GraphQL queries in the component tree
// and extract the resulting data
const apollo = initApollo()
try {
// Run all GraphQL queries
await getDataFromTree(
<App
{...appProps}
Component={Component}
router={router}
apolloState={apolloState}
apolloClient={apollo}
/>
)
} catch (error) {
// Prevent Apollo Client GraphQL errors from crashing SSR.
// Handle them in components via the data.error prop:
// http://dev.apollodata.com/react/api-queries.html#graphql-query-data-error
console.error('Error while running `getDataFromTree`', error)
}
if (!process.browser) {
try {
// Run all GraphQL queries
await getDataFromTree(
<App
{...appProps}
Component={Component}
router={router}
apolloState={apolloState}
apolloClient={apollo}
/>
)
} catch (error) {
// Prevent Apollo Client GraphQL errors from crashing SSR.
// Handle them in components via the data.error prop:
// http://dev.apollodata.com/react/api-queries.html#graphql-query-data-error
console.error('Error while running `getDataFromTree`', error)
}
// getDataFromTree does not call componentWillUnmount
// head side effect therefore need to be cleared manually
Head.rewind()
}
// Extract query data from the Apollo store
apolloState.data = apollo.cache.extract()
// Extract query data from the Apollo store
apolloState.data = apollo.cache.extract()
} else {
apolloState.data = {}
}
return {
...appProps,
@ -53,9 +55,7 @@ export default (App) => {
constructor (props) {
super(props)
// `getDataFromTree` renders the component first, the client is passed off as a property.
// After that rendering is done using Next's normal rendering pipeline
this.apolloClient = props.apolloClient || initApollo(props.apolloState.data)
this.apolloClient = initApollo(props.apolloState.data)
}
render () {