From 3033b582ec9257d5d179e3078a589a248cbcf8cf Mon Sep 17 00:00:00 2001 From: Jayden Seric Date: Thu, 10 Aug 2017 19:30:04 +1000 Subject: [PATCH] Simplified withData decorator. --- app/helpers/init-apollo-client.js | 39 ------------------------- app/helpers/with-data.js | 47 +++++++++++++++++++++++++------ 2 files changed, 39 insertions(+), 47 deletions(-) delete mode 100644 app/helpers/init-apollo-client.js diff --git a/app/helpers/init-apollo-client.js b/app/helpers/init-apollo-client.js deleted file mode 100644 index 0919741..0000000 --- a/app/helpers/init-apollo-client.js +++ /dev/null @@ -1,39 +0,0 @@ -import { ApolloClient } from 'react-apollo' -import BatchHttpLink from 'apollo-link-batch-http' -import { createApolloFetchUpload } from 'apollo-fetch-upload' - -// Used in the browser to share a single Apollo Client instance between -// decorated components. -let apolloClient = null - -/** - * Creates a new Apollo Client instance. - * @param {Object} [initialState] - Apollo client Redux store initial state. - * @returns {Object} Apollo Client instance. - */ -const createApolloClient = initialState => - new ApolloClient({ - initialState, - ssrMode: !process.browser, - networkInterface: new BatchHttpLink({ - fetch: createApolloFetchUpload({ - uri: process.env.API_URI - }) - }) - }) - -/** - * Gets or creates the Apollo Client instance. - * @param {Object} [initialState] - Apollo client Redux store initial state. - * @returns {Object} Apollo Client instance. - */ -export default function initApolloClient(initialState) { - // Create a new client every server-side request so that data isn't shared - // between connections. - if (!process.browser) return createApolloClient(initialState) - - // Reuse client on the client-side. - if (!apolloClient) apolloClient = createApolloClient(initialState) - - return apolloClient -} diff --git a/app/helpers/with-data.js b/app/helpers/with-data.js index 7cc2956..4301c36 100644 --- a/app/helpers/with-data.js +++ b/app/helpers/with-data.js @@ -1,8 +1,30 @@ import { Component } from 'react' -import { ApolloProvider, getDataFromTree } from 'react-apollo' +import { ApolloClient, getDataFromTree, ApolloProvider } from 'react-apollo' +import BatchHttpLink from 'apollo-link-batch-http' +import { createApolloFetchUpload } from 'apollo-fetch-upload' import getDisplayName from 'react-display-name' import Head from 'next/head' -import initApolloClient from './init-apollo-client' + +const ssrMode = !process.browser + +// To share an instance between pages on the client +let apolloClient + +/** + * Creates a new Apollo Client instance. + * @param {Object} [initialState] - Redux initial state. + * @returns {Object} Apollo Client instance. + */ +const createApolloClient = initialState => + new ApolloClient({ + initialState, + ssrMode, + networkInterface: new BatchHttpLink({ + fetch: createApolloFetchUpload({ + uri: process.env.API_URI + }) + }) + }) export default ComposedComponent => { return class WithData extends Component { @@ -43,8 +65,8 @@ export default ComposedComponent => { ) } - if (!process.browser) { - const apolloClient = initApolloClient() + if (ssrMode) { + const apolloClient = createApolloClient() try { // Recurse the component tree and prefetch all Apollo data queries to @@ -60,6 +82,8 @@ export default ComposedComponent => { // 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 + // eslint-disable-next-line no-console + console.error(error) } // Forget Head items found during the getDataFromTree render to prevent @@ -68,17 +92,24 @@ export default ComposedComponent => { // Set Apollo Client initial state so the client can adopt data fetched // on the server. - initialProps.initialState = { - apollo: apolloClient.getInitialState() - } + initialProps.initialState = { apollo: apolloClient.getInitialState() } } + // Return the final page component inital props return initialProps } constructor(props) { super(props) - this.apolloClient = initApolloClient(this.props.initialState) + if (ssrMode) { + // For the server an Apollo Client instance exists per request + this.apolloClient = createApolloClient(this.props.initialState) + } else { + // For the client an Apollo Client instance is shared between pages + if (!apolloClient) + apolloClient = createApolloClient(this.props.initialState) + this.apolloClient = apolloClient + } } render() {