ran-boilerplate
Version:
React . Apollo (GraphQL) . Next.js Toolkit
97 lines (84 loc) • 2.35 kB
JavaScript
// @flow
import * as React from 'react';
import { ApolloProvider, getDataFromTree } from 'react-apollo';
import PropTypes from 'prop-types';
import 'isomorphic-fetch';
import cookies from 'next-cookies';
import apolloClient from './apolloClient';
import reduxStore from './reduxStore';
import persist from './persist';
type Props = {
headers: HeadersType,
accessToken: ?string,
initialState: Object,
url: UrlType
};
type Context = {
pathname: string,
query: Object,
asPath: string,
req?: {
headers?: Object
},
res?: Object,
jsonPageRes?: Object,
err?: Object
};
export default (
Component: React.ComponentType<*>
): React.ComponentType<Props> =>
class extends React.Component<Props> {
static propTypes = {
headers: PropTypes.object.isRequired,
accessToken: PropTypes.string,
initialState: PropTypes.object.isRequired
};
static defaultProps = {
accessToken: null
};
static async getInitialProps(ctx: Context) {
const headers = ctx.req ? ctx.req.headers : {};
const token: string = cookies(ctx)[persist.ACCESS_TOKEN_KEY];
const client = apolloClient(headers, token);
const store = reduxStore(client, client.initialState, token);
const props = {
url: { query: ctx.query, pathname: ctx.pathname },
...(await (typeof Component.getInitialProps === 'function'
? Component.getInitialProps(ctx)
: {}))
};
if (!process.browser) {
const app = (
<ApolloProvider client={client} store={store}>
<Component {...props} />
</ApolloProvider>
);
await getDataFromTree(app);
}
const state = store.getState();
return {
initialState: {
...state,
apollo: {
data: state.apollo.data
}
},
headers,
...props
};
}
constructor(props: Props) {
super(props);
this.apolloClient = apolloClient(this.props.headers);
this.reduxStore = reduxStore(this.apolloClient, this.props.initialState);
}
apolloClient: Object;
reduxStore: Object;
render() {
return (
<ApolloProvider client={this.apolloClient} store={this.reduxStore}>
<Component {...this.props} />
</ApolloProvider>
);
}
};