next-redux-wrapper
next-redux-wrapper copied to clipboard
getInitialProps only example or some config option
Is your feature request related to a problem? Please describe.
In the version 6 the HYDRATE
action was introduced. I guess it was done to allow the usage of getServerSideProps
and getStaticProps
. At the same time it has made working with getInitialProps
a bit more complex.
Even though the HYDRATE
action theoretically allows working with getServerSideProps
and getStaticProps
, the Redux itself is not very much friendly with SSR and hydrating state with getServerSideProps
and (or) getStaticProps
brings that much pain that it nets off all the potential benefits of those two new data fetching methods. So to my humble opinion working with getInitialProps
only and Redux may be the only real reliable and scalable solution for big enterprise level apps.
So it can justify either some example or maybe a config switch to revert to version 5 behaviour with initialState
Describe the solution you'd like
Below is the code that I put into reducer.js
file to kind of emulate the version 5 functionality with getInitialProps
only.
I would be interested to know if I did it right and if it could be the recommended solution for the above described case. All my tests so far showed that it looks to work.
import { combineReducers } from 'redux'
import { shop } from '../modules/shop'
import { user } from '../modules/user'
import { cart } from '../modules/cart'
import { HYDRATE } from 'next-redux-wrapper'
// These are normal 'business' reducers
const combinedReducer = combineReducers({
shop,
user,
cart,
})
// This is a technical reducer to merge (hydrate) the initial state from SSR
const hydrate = (state = {}, action) => {
const { type } = action
switch (type) {
case HYDRATE: {
return { ...state, ...action.payload }
}
default:
return state
}
}
// Since the hydrate reducer should work on the root level
// I need to merge them like that
const rootReducer = (state, action) => {
const intermediateState = combinedReducer(state, action)
return hydrate(intermediateState, action)
}
export default rootReducer
One thing is still unclear though. Even with the client side navigation with the page containing only getInitialProps
I still see the HYDRATE
action being fired which is doing nothing. It just returns the current client state in the action.payload
. Maybe it would be good not to fire that action in this case at all.
getInitialProps
is always executed when a page is moved, and when a hydrate
action occurs, the client's state is overwritten with the server's state. So the hydrate
action should be executed when the page is first rendered (SSR), not the hydrate
action when the CSR is executed.
https://www.npmjs.com/package/compose-hydrate-reducers Try this. This allows the state to be synchronized only when the page is first rendered (SSR).