gajus / redux-immutable

redux-immutable is used to create an equivalent function of Redux combineReducers that works with Immutable.js state.
Other
1.88k stars 82 forks source link

set-up help #41

Closed Jbarget closed 8 years ago

Jbarget commented 8 years ago

Hey there, just trying to convert a current app to deal with immutable state and running into some troubles. The state my components are receiving are still in the Immutable.js form.

Map {size: 9, _root: BitmapIndexedNode, __ownerID: undefined, __hash: undefined, __altered: false}

Any help will be great as I cant seem to figure out where exactly im going wrong although I think its the way im orgainsing configureStore.js below. (I've taken the majority of the app out for simplicity)

thanks

reducer.js:

import { REHYDRATE } from 'redux-persist/constants';
import Immutable from 'immutable';

const initialState = Immutable.Map({
  rehydrated: false,
  isLoggedIn: false
});

const Login = (state = initialState, action) => {
  switch (action.type) {
  case REHYDRATE:
    const incoming = action.payload;
    if (incoming.reducers) {
      return state.merge(incoming.reducers.login).set('rehydrated', true);
    }
    return state.set('rehydrated', true);
  case 'AUTHORISE_SUCCESS':
    return state.set('isLoggedIn', true);
  case 'AUTHORISE_FAILURE':
    return state.set('isLoggedIn', false);
  case 'LOGOUT_SUCCESS':
    return state.set('isLoggedIn', false);
  default:
    return state;
  }
};

export default Login;

combineReducers.js:

import { combineReducers } from 'redux-immutable';

import login from './login';
import routing from './routing';

const rootReducer = combineReducers({
  login,
  routing
});

export default rootReducer;

configureStore.js:

import thunkMiddleware from 'redux-thunk';
import { autoRehydrate } from 'redux-persist';
import { routerMiddleware } from 'react-router-redux';
import rootReducer from '../reducers/index';
import { createStore, applyMiddleware, compose } from 'redux';
import Immutable from 'immutable';

const initialState = Immutable.Map();

export default function configureStore(browserHistory) {
  return createStore(
    rootReducer,
    initialState,
    compose(
      autoRehydrate(),
      applyMiddleware(thunkMiddleware, routerMiddleware(browserHistory))
    )
  );
}

export default configureStore;

index.js:

import * as React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { syncHistoryWithStore } from 'react-router-redux';
import { Router, Route, browserHistory } from 'react-router';

import AuthCheckHOC from './components/AuthCheckHOC';
import PersisterHOC from './components/PersisterHOC';
import Container from './containers/Container';
import Auth from './containers/Auth';

import configureStore from './store/configureStore';

const store = configureStore(browserHistory);
const history = syncHistoryWithStore(browserHistory, store, {
  selectLocationState(state) {
    return state.get('routing').toJS();
  }
});
ReactDOM.render(
  <Provider store={store}>
    <Router history={history}>
      {/*'/signin' route needs to be outside PersisterHOC and AuthCheckHOC*/}
      <Route path="/signin" component={Auth} />
      <Route component={PersisterHOC(AuthCheckHOC(Container), store)}>
      </Route>
    </Router>
  </Provider>,
  document.getElementById('react-content')
);
gajus commented 8 years ago

The state my components are receiving are still in the Immutable.js form.

Thats expected.

You can either use instances of Immutabe.js in your components as you have received them, or you can convert them to plain objects in the (since you are using Redux) mapStateToProps callback.

Jbarget commented 8 years ago

oh gotcha! would you be able to point me to whats the best way of doing that as i've read toJS() isnt that performant

https://github.com/reactjs/react-redux/issues/60

gajus commented 8 years ago

oh gotcha! would you be able to point me to whats the best way of doing that as i've read toJS() isnt that performant

There is nothing wrong with using toJS in this scenario. (As long as you limit the scope of selected data to only whats needed and not the entire state.)

gajus commented 8 years ago

Please close the issue if it answers your question.

Jbarget commented 8 years ago

it certainly does! really appreciate it!

although just tried this:

const mapStateToProps = (state) => {
  return {
    loginRehydrated: state.get('login').toJS().rehydrated
  };
};

and getting Uncaught TypeError: state.get is not a function last thing :)

gajus commented 8 years ago

and getting Uncaught TypeError: state.get is not a function last thing :)

This is unrelated to the original question and outside of the redux-immutable scope. Refer to Immutable.js documentation.

Jbarget commented 8 years ago

👍 thanks again

gajus commented 8 years ago

(I would start by inspecting state value, and tracing its origin, since it doesn't look like it is an instance of Immutable).

AlexisBarta commented 8 years ago

@Jbarget I've got the same problem Uncaught TypeError: state.get is not a function did you find a solution?

Jbarget commented 8 years ago

Our front-end architecture changed so we didnt need to add immutable state management. My original problem was that I wasn't accessing my state correctly

AlexisBarta commented 8 years ago

@Jbarget Thanks for your answer.

dreamcatcher081210 commented 7 years ago

@gajus 在redux-immutable里是否对set方法进行了特殊处理从而在组件里可以获取到JS Object?而merge方法没有进行特殊处理?