mirror of
https://github.com/terribleplan/next.js.git
synced 2024-01-19 02:48:18 +00:00
728871b005
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.
66 lines
1.8 KiB
JavaScript
66 lines
1.8 KiB
JavaScript
import initApollo from './init-apollo'
|
|
import Head from 'next/head'
|
|
import { getDataFromTree } from 'react-apollo'
|
|
|
|
export default (App) => {
|
|
return class Apollo extends React.Component {
|
|
static displayName = 'withApollo(App)'
|
|
static async getInitialProps (ctx) {
|
|
const { Component, router } = ctx
|
|
|
|
let appProps = {}
|
|
if (App.getInitialProps) {
|
|
appProps = await App.getInitialProps(ctx)
|
|
}
|
|
|
|
const apolloState = {}
|
|
|
|
// Run all GraphQL queries in the component tree
|
|
// and extract the resulting data
|
|
const apollo = initApollo()
|
|
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()
|
|
} else {
|
|
apolloState.data = {}
|
|
}
|
|
|
|
return {
|
|
...appProps,
|
|
apolloState
|
|
}
|
|
}
|
|
|
|
constructor (props) {
|
|
super(props)
|
|
this.apolloClient = initApollo(props.apolloState.data)
|
|
}
|
|
|
|
render () {
|
|
return <App {...this.props} apolloClient={this.apolloClient} />
|
|
}
|
|
}
|
|
}
|