diff --git a/examples/with-rematch/pages/_app.js b/examples/with-rematch/pages/_app.js index 68b2f632755cc..518e8678e6171 100644 --- a/examples/with-rematch/pages/_app.js +++ b/examples/with-rematch/pages/_app.js @@ -1,17 +1,12 @@ -import App from 'next/app' import { Provider } from 'react-redux' +import { useStore } from '../shared/store' -import withRematch from '../shared/withRematch' +export default function App({ Component, pageProps }) { + const store = useStore(pageProps.initialReduxState) -class MyApp extends App { - render() { - const { Component, pageProps, reduxStore } = this.props - return ( - - - - ) - } + return ( + + + + ) } - -export default withRematch(MyApp) diff --git a/examples/with-rematch/shared/store.js b/examples/with-rematch/shared/store.js index 0ba394fce13ff..a663731a024e0 100644 --- a/examples/with-rematch/shared/store.js +++ b/examples/with-rematch/shared/store.js @@ -1,11 +1,14 @@ +import { useMemo } from 'react' import { init } from '@rematch/core' import { counter, github } from './models' +let store + const exampleInitialState = { counter: 5, } -export const initializeStore = (initialState = exampleInitialState) => +export const initStore = (initialState = exampleInitialState) => init({ models: { counter, @@ -15,3 +18,30 @@ export const initializeStore = (initialState = exampleInitialState) => initialState, }, }) + +export const initializeStore = (preloadedState) => { + let _store = store ?? initStore(preloadedState) + + // After navigating to a page with an initial Redux state, merge that state + // with the current state in the store, and create a new store + if (preloadedState && store) { + _store = initStore({ + ...store.getState(), + ...preloadedState, + }) + // Reset the current store + store = undefined + } + + // For SSG and SSR always create a new store + if (typeof window === 'undefined') return _store + // Create the store once in the client + if (!store) store = _store + + return _store +} + +export function useStore(initialState) { + const store = useMemo(() => initializeStore(initialState), [initialState]) + return store +} diff --git a/examples/with-rematch/shared/withRematch.js b/examples/with-rematch/shared/withRematch.js deleted file mode 100644 index bea90e1549bf5..0000000000000 --- a/examples/with-rematch/shared/withRematch.js +++ /dev/null @@ -1,51 +0,0 @@ -import React from 'react' - -import { checkServer } from './utils' -import { initializeStore } from './store' - -const __NEXT_REDUX_STORE__ = '__NEXT_REDUX_STORE__' - -function getOrCreateStore(initialState) { - // Always make a new store if server, otherwise state is shared between requests - if (checkServer()) { - return initializeStore(initialState) - } - - // Create store if unavailable on the client and set it on the window object - if (!window[__NEXT_REDUX_STORE__]) { - window[__NEXT_REDUX_STORE__] = initializeStore(initialState) - } - return window[__NEXT_REDUX_STORE__] -} - -export default function withRematch(App) { - return class AppWithRematch extends React.Component { - static async getInitialProps(appContext) { - // Get or Create the store with `undefined` as initialState - // This allows you to set a custom default initialState - const reduxStore = getOrCreateStore() - - // Provide the store to getInitialProps of pages - appContext.ctx.reduxStore = reduxStore - - let appProps = {} - if (typeof App.getInitialProps === 'function') { - appProps = await App.getInitialProps(appContext) - } - - return { - ...appProps, - initialReduxState: reduxStore.getState(), - } - } - - constructor(props) { - super(props) - this.reduxStore = getOrCreateStore(props.initialReduxState) - } - - render() { - return - } - } -}