1
0
Fork 0
mirror of https://github.com/terribleplan/next.js.git synced 2024-01-19 02:48:18 +00:00
next.js/examples/with-apollo/lib/withData.js
Wes Bos 3949c82bdf Add missing url prop (#4078)
This was causing react-apollo  to crash on any SSR page that needed the page's query to make the GraphQL queries. 

It's magically passed on the client, but we have to manually pass it to the composed component here
2018-03-29 18:01:12 +02:00

93 lines
2.5 KiB
JavaScript

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) {
// Initial serverState with apollo (empty)
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
const apollo = initApollo()
try {
// create the url prop which is passed to every page
const url = {
query: ctx.query,
asPath: ctx.asPath,
pathname: ctx.pathname,
};
// Run all GraphQL queries
await getDataFromTree(
<ComposedComponent ctx={ctx} url={url} {...composedInitialProps} />,
{
router: {
asPath: ctx.asPath,
pathname: ctx.pathname,
query: ctx.query
},
client: 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
}
if (!process.browser) {
// getDataFromTree does not call componentWillUnmount
// head side effect therefore need to be cleared manually
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>
)
}
}
}