From 222ab374d53a206332b1ab51c7c43f6d5dc7a31e Mon Sep 17 00:00:00 2001 From: Wes Bos Date: Tue, 8 Aug 2017 22:09:05 -0400 Subject: yep --- lib/withData.js | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 lib/withData.js (limited to 'lib/withData.js') diff --git a/lib/withData.js b/lib/withData.js new file mode 100644 index 0000000..4720790 --- /dev/null +++ b/lib/withData.js @@ -0,0 +1,80 @@ +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( + + + + ) + } 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 + Head.rewind() + + // Extract query data from the Apollo store + const state = apollo.getInitialState() + + serverState = { + apollo: { + // Only include the Apollo data state + data: state.data + } + } + } + + return { + serverState, + ...composedInitialProps + } + } + + constructor (props) { + super(props) + this.apollo = initApollo(this.props.serverState) + } + + render () { + return ( + + + + ) + } + } +} -- cgit v1.3