import * as React from 'react' ; import { Provider } from 'react-redux' ; import Head from 'next/head' ; import { ApolloProvider , getDataFromTree } from 'react-apollo' ; import { initApollo } from './apollo' ; import { initRedux } from './store' ; const proc = process as any ; function getComponentDisplayName ( Component ) { return Component . displayName || Component . name || 'Unknown' ; } export default ( ComposedComponent ) => { return class WithData extends React . Component { public apollo ; public redux ; public displayName = `WithData(${ getComponentDisplayName ( ComposedComponent ) })` ; public async getInitialProps ( ctx ) { let serverState = { } ; let composedInitialProps = { } ; if ( ComposedComponent . getInitialProps ) { composedInitialProps = await ComposedComponent . getInitialProps ( ctx ) ; } if ( ! proc . browser ) { const apollo = initApollo ( ) ; const redux = initRedux ( ) ; const url = { query : ctx . query , pathname : ctx . pathname } ; try { await getDataFromTree ( < ApolloProvider client = { apollo } > < Provider store = { redux } > < ComposedComponent url = { url } { ... composedInitialProps } / > < /Provider> < /ApolloProvider>); } catch ( error ) { } Head . rewind ( ) ; const state = redux . getState ( ) ; serverState = { apollo : { data : state . apollo . data } } ; } return { serverState , ... composedInitialProps } ; } constructor ( props ) { super ( props ) ; const { serverState } = this . props ; this . apollo = initApollo ( ) ; this . redux = initRedux ( serverState ) ; } public render ( ) { return ( < ApolloProvider client = { this . apollo } > < Provider store = { this . redux } > < ComposedComponent { ... this . props } / > < /Provider> < /ApolloProvider>); } } ; } ;