next-redux-wrapper icon indicating copy to clipboard operation
next-redux-wrapper copied to clipboard

getInitialProps only example or some config option

Open slava-lu opened this issue 3 years ago • 1 comments

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.

slava-lu avatar Nov 14 '21 13:11 slava-lu

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).

stegano avatar Dec 24 '21 13:12 stegano