Next.js: Redux example does not work with combineReducers

Created on 12 Feb 2017  路  1Comment  路  Source: vercel/next.js

I am having trouble converting the with-redux example to use combineReducers.

I have made a repo to demonstrate the issue.

The last two commits are the most informative, but read on for a more detailed explanation.

Converting to combineReducers

For context, this commit shows how I performed the attempted conversion:
https://github.com/adrianmcli/with-redux-combineReducers/commit/300d71622b8fb6d22baade5163b2eed9a263d64b

The problem

Line 9 of the with-redux example uses null as the second argument of the initStore function (which is basically just the createStore function from Redux).

const store = initStore(reducer, null, isServer)

This is okay when the reducer is a regular reducer. But when the reducer being passed in is a "combined reducer", the second argument of that function call needs to be an object that reflects the shape of the combined reducer.

According to the Redux docs, under the paragraph for [preloadedState]:

If you produced reducer with combineReducers, this must be a plain object with the same shape as the keys passed to it.

As a result, I get the following error:

The preloadedState argument passed to createStore has unexpected type of "Null". Expected argument to be an object with the following keys: "clock"

Quick fix

The quick fix for the problem is simple, we simply pass in { clock: null } instead of just null.

const store = initStore(reducer, { clock: null }, isServer)

This commit shows exactly that:
https://github.com/adrianmcli/with-redux-combineReducers/commit/c199e2e0f89d1bb658b8ca3246a28e65395c5f0c

Not a good fix

But this is not a good fix, because this means that every page that calls initStore will need to know the entire structure of the reducers.

This will make it very difficult to add new reducers, because you'll have to update { clock: null } everywhere that createStore/initStore is used, eventually ballooning it to become something like:

{
  clock: null,
  someState: null,
  someOtherState: null,
  yetAnotherState: null
}

Is there a better way to convert this example to use combineReducers while maintaining good idiomatic best practices along with fully functional server side rendering?

Most helpful comment

Apparently the key isn't really required. This works just as well:

const store = initStore(reducer, {}, isServer)

Thanks to @rohannair for helping me out on this one.

>All comments

Apparently the key isn't really required. This works just as well:

const store = initStore(reducer, {}, isServer)

Thanks to @rohannair for helping me out on this one.

Was this page helpful?
0 / 5 - 0 ratings