mirror of
https://github.com/seigler/triplebyte-react-spa
synced 2025-07-26 07:16:10 +00:00
72 lines
2.1 KiB
JavaScript
72 lines
2.1 KiB
JavaScript
import React from 'react'
|
|
import { Provider } from 'react-redux'
|
|
import { initializeStore } from '../store'
|
|
import App from 'next/app'
|
|
|
|
export const withRedux = (PageComponent, { ssr = true } = {}) => {
|
|
const WithRedux = ({ initialReduxState, ...props }) => {
|
|
const store = getOrInitializeStore(initialReduxState)
|
|
return (
|
|
<Provider store={store}>
|
|
<PageComponent {...props} />
|
|
</Provider>
|
|
)
|
|
}
|
|
|
|
// Make sure people don't use this HOC on _app.js level
|
|
if (process.env.NODE_ENV !== 'production') {
|
|
const isAppHoc =
|
|
PageComponent === App || PageComponent.prototype instanceof App
|
|
if (isAppHoc) {
|
|
throw new Error('The withRedux HOC only works with PageComponents')
|
|
}
|
|
}
|
|
|
|
// Set the correct displayName in development
|
|
if (process.env.NODE_ENV !== 'production') {
|
|
const displayName =
|
|
PageComponent.displayName || PageComponent.name || 'Component'
|
|
|
|
WithRedux.displayName = `withRedux(${displayName})`
|
|
}
|
|
|
|
if (ssr || PageComponent.getInitialProps) {
|
|
WithRedux.getInitialProps = async context => {
|
|
// Get or Create the store with `undefined` as initialState
|
|
// This allows you to set a custom default initialState
|
|
const reduxStore = getOrInitializeStore()
|
|
|
|
// Provide the store to getInitialProps of pages
|
|
context.reduxStore = reduxStore
|
|
|
|
// Run getInitialProps from HOCed PageComponent
|
|
const pageProps =
|
|
typeof PageComponent.getInitialProps === 'function'
|
|
? await PageComponent.getInitialProps(context)
|
|
: {}
|
|
|
|
// Pass props to PageComponent
|
|
return {
|
|
...pageProps,
|
|
initialReduxState: reduxStore.getState(),
|
|
}
|
|
}
|
|
}
|
|
|
|
return WithRedux
|
|
}
|
|
|
|
let reduxStore
|
|
const getOrInitializeStore = initialState => {
|
|
// Always make a new store if server, otherwise state is shared between requests
|
|
if (typeof window === 'undefined') {
|
|
return initializeStore(initialState)
|
|
}
|
|
|
|
// Create store if unavailable on the client and set it on the window object
|
|
if (!reduxStore) {
|
|
reduxStore = initializeStore(initialState)
|
|
}
|
|
|
|
return reduxStore
|
|
}
|