Skip to content
This repository has been archived by the owner on Jan 24, 2024. It is now read-only.

Commit

Permalink
add: hoc for injecting Redux store into next.js app
Browse files Browse the repository at this point in the history
  • Loading branch information
sota1235 committed Sep 23, 2019
1 parent 4c134ab commit 9a00a89
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 0 deletions.
65 changes: 65 additions & 0 deletions src/hoc/withReduxStore.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { NextComponentType, NextPageContext } from 'next';
import { AppContext } from "next/app";
import React from 'react'
import {Action, AnyAction, Store} from "redux";
import { getStore } from '../configureStore'
import { createRootReducer } from "../reducers";
import Any = jasmine.Any;

const isServer = typeof window === 'undefined';
export const __NEXT_REDUX_STORE__ = '__NEXT_REDUX_STORE__';

const rootReducer = createRootReducer();

export interface NextJSContext<S = any, A extends Action = AnyAction> extends NextPageContext {
store: Store<S, A>;
}

export interface NextJSAppContext<S = any, A extends Action = AnyAction> extends AppContext {
ctx: NextJSContext<S, A>;
}

function getOrCreateStore (initialState?: {}): Store {
// Always make a new store if server, otherwise state is shared between requests
if (isServer) {
return getStore(rootReducer, initialState)
}

// Create store if unavailable on the client and set it on the window object
if (!window.hasOwnProperty(__NEXT_REDUX_STORE__)) {
window[__NEXT_REDUX_STORE__] = getStore(rootReducer, initialState)
}
return window[__NEXT_REDUX_STORE__]
}

export function withReduxStore<NextAppProps, S = any, A extends Action = AnyAction>(App: NextComponentType<NextJSAppContext<S, A>>) {
type Props = NextAppProps & { initialReduxState: Store };
return class AppWithRedux extends React.Component<Props> {

public static async getInitialProps (appContext: NextJSAppContext) {
const store = getOrCreateStore();

appContext.ctx.store = store;

let appProps = {};
if (typeof App.getInitialProps === 'function') {
appProps = await App.getInitialProps(appContext);
}

return {
...appProps,
initialReduxState: store.getState()
}
}
protected reduxStore: Store;

constructor (props: Props) {
super(props);
this.reduxStore = getOrCreateStore(props.initialReduxState);
}

public render () {
return <App {...this.props} reduxStore={this.reduxStore} />
}
}
}
7 changes: 7 additions & 0 deletions src/types/global.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import {Store} from "redux";

declare global {
interface Window {
__NEXT_REDUX_STORE__: Store;
}
}
1 change: 1 addition & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
],
"include": [
"next-env.d.ts",
"src/types/*.d.ts",
"**/*.ts",
"**/*.tsx"
]
Expand Down

0 comments on commit 9a00a89

Please sign in to comment.