erikras / react-redux-universal-hot-example

A starter boilerplate for a universal webapp using express, react, redux, webpack, and react-transform
MIT License
12.01k stars 2.5k forks source link

Redux state being serialized #1313

Closed sslotsky closed 7 years ago

sslotsky commented 7 years ago

The redux state for violet-paginator is supposed to be an Immutable.List. When running your example, however, store.getState().pagination evaluates to an array. This breaks all of my reducer code.

I could not track down what's causing the state to be serialized. I suspect there's some step during your initial setup that is doing it. Any ideas? I can submit an incomplete PR if that would help the investigation.

sslotsky commented 7 years ago

And just like that I think I found it. It's because liftReducer is being used. Any suggestions here?

sslotsky commented 7 years ago

With a little hack I can force data.pagination back into a List, but then it's onto the next hurdle. It seems that redux-devtools-instrument does not believe that I've integrated thunk correctly.

import { createStore as _createStore, applyMiddleware, compose } from 'redux';
import createMiddleware from './middleware/clientMiddleware';
import { routerMiddleware } from 'react-router-redux';
import thunk from 'redux-thunk';
import Immutable from 'immutable';

export default function createStore(history, client, data) {
  // Sync dispatched route actions to the history
  const reduxRouterMiddleware = routerMiddleware(history);

  const middleware = [createMiddleware(client), reduxRouterMiddleware, thunk];

  let finalCreateStore;
  if (__DEVELOPMENT__ && __CLIENT__ && __DEVTOOLS__) {
    const { persistState } = require('redux-devtools');
    const DevTools = require('../containers/DevTools/DevTools');
    finalCreateStore = compose(
      applyMiddleware(...middleware),
      window.devToolsExtension ? window.devToolsExtension() : DevTools.instrument(),
      persistState(window.location.href.match(/[?&]debug_session=([^&]+)\b/))
    )(_createStore);
  } else {
    finalCreateStore = applyMiddleware(...middleware)(_createStore);
  }

  const reducer = require('./modules/reducer');
  if (data) {
    data.pagination = Immutable.fromJS(data.pagination);
  }
  const store = finalCreateStore(reducer, data);

Looking at the stack trace, it seems that actions are lifted too, so I wonder if that has something to do with it. Does redux-devtools-instrument simply not integrate with things like thunk and Immutable? Should we consider a different devtools extension for this project?

redux-devtools-instrument

sslotsky commented 7 years ago

I suspect that the server rendering is also playing some role in this, as well as me just not fully understanding how to use the redux API in that scenario. I'm calling it a day for now but I'm going to submit a [DO NOT MERGE] PR to link to this issue and would really appreciate your thoughts @erikras

sslotsky commented 7 years ago

Update on the thunk issue, this is a case of me forgetting how to use my own library. My mockFetch wasn't setup correctly.

However, advice on a non-hacky way to get state.pagination to stay immutable is still very much desired.