Created
November 16, 2017 09:20
-
-
Save timneutkens/98cd9b4f739d3ffb3a2c56d7ac9eef42 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 React from 'react' | |
import PropTypes from 'prop-types' | |
import { ApolloProvider, getDataFromTree } from 'react-apollo' | |
import Head from 'next/head' | |
import initApollo from './initApollo' | |
// Gets the display name of a JSX component for dev tools | |
function getComponentDisplayName (Component) { | |
return Component.displayName || Component.name || 'Unknown' | |
} | |
export default ComposedComponent => { | |
return class WithData extends React.Component { | |
static displayName = `WithData(${getComponentDisplayName(ComposedComponent)})` | |
static propTypes = { | |
serverState: PropTypes.object.isRequired | |
} | |
static async getInitialProps (ctx) { | |
let serverState = {} | |
// Evaluate the composed component's getInitialProps() | |
let composedInitialProps = {} | |
if (ComposedComponent.getInitialProps) { | |
composedInitialProps = await ComposedComponent.getInitialProps(ctx) | |
} | |
// Run all GraphQL queries in the component tree | |
// and extract the resulting data | |
// if (!process.browser) { | |
const apollo = initApollo() | |
// Provide the `url` prop data in case a GraphQL query uses it | |
const url = {query: ctx.query, pathname: ctx.pathname} | |
try { | |
// Run all GraphQL queries | |
await getDataFromTree( | |
<ApolloProvider client={apollo}> | |
<ComposedComponent url={url} {...composedInitialProps} /> | |
</ApolloProvider> | |
) | |
} 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 | |
} | |
// getDataFromTree does not call componentWillUnmount | |
// head side effect therefore need to be cleared manually | |
if(!process.browser) { | |
Head.rewind() | |
} | |
// Extract query data from the Apollo store | |
serverState = { | |
apollo: { | |
data: apollo.cache.extract() | |
} | |
} | |
// } | |
return { | |
serverState, | |
...composedInitialProps | |
} | |
} | |
constructor (props) { | |
super(props) | |
this.apollo = initApollo(this.props.serverState.apollo.data) | |
} | |
render () { | |
return ( | |
<ApolloProvider client={this.apollo}> | |
<ComposedComponent {...this.props} /> | |
</ApolloProvider> | |
) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment