mirror of
https://github.com/terribleplan/next.js.git
synced 2024-01-19 02:48:18 +00:00
1a8bdba56b
App component does not need/use apolloState prop, so let's remove it. If I'm wrong please explain me the purpose of this.
94 lines
2.6 KiB
JavaScript
94 lines
2.6 KiB
JavaScript
import React from 'react'
|
|
import cookie from 'cookie'
|
|
import PropTypes from 'prop-types'
|
|
import { getDataFromTree } from 'react-apollo'
|
|
import Head from 'next/head'
|
|
|
|
import initApollo from './initApollo'
|
|
|
|
function parseCookies(req, options = {}) {
|
|
return cookie.parse(
|
|
req ? req.headers.cookie || '' : document.cookie,
|
|
options
|
|
)
|
|
}
|
|
|
|
export default App => {
|
|
return class WithData extends React.Component {
|
|
static displayName = `WithData(${App.displayName})`
|
|
static propTypes = {
|
|
apolloState: PropTypes.shape({
|
|
data: PropTypes.object.isRequired
|
|
}).isRequired
|
|
}
|
|
|
|
static async getInitialProps(ctx) {
|
|
const { Component, router, ctx: { req, res } } = ctx
|
|
const apollo = initApollo({}, {
|
|
getToken: () => parseCookies(req).token
|
|
})
|
|
|
|
ctx.ctx.apolloClient = apollo
|
|
|
|
let appProps = {}
|
|
if (App.getInitialProps) {
|
|
appProps = await App.getInitialProps(ctx)
|
|
}
|
|
|
|
if (res && res.finished) {
|
|
// When redirecting, the response is finished.
|
|
// No point in continuing to render
|
|
return {}
|
|
}
|
|
|
|
// Run all graphql queries in the component tree
|
|
// and extract the resulting data
|
|
try {
|
|
// Run all GraphQL queries
|
|
await getDataFromTree(
|
|
<App
|
|
{...appProps}
|
|
Component={Component}
|
|
router={router}
|
|
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) {
|
|
// getDataFromTree does not call componentWillUnmount
|
|
// head side effect therefore need to be cleared manually
|
|
Head.rewind()
|
|
}
|
|
|
|
// Extract query data from the Apollo's store
|
|
const apolloState = { data: apollo.cache.extract() }
|
|
|
|
return {
|
|
...appProps,
|
|
apolloState
|
|
}
|
|
}
|
|
|
|
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, {
|
|
getToken: () => parseCookies().token
|
|
})
|
|
}
|
|
|
|
render() {
|
|
return <App {...this.props} apolloClient={this.apolloClient} />
|
|
}
|
|
}
|
|
}
|