Correct way to use immutablejs (toJS and fromJS) w

2019-08-05 07:00发布

问题:

I wonder if this is a correct way to use immutable.js with redux and reselect (also redux-saga). Specifically I wonder about toJS() and from fromJS() and where to use them. My idea is that:

  1. I use toJS() when sending data to a saga.
  2. I do not use fromJS() in reducer because I think that it is done anyway by the fact that I use fromJS() for initialState. Or am I wrong about that?
  3. I use toJS() in selector from reselect so I can use js data in react component.

Example:

1) In my react component I do:

// mapDispatchToProps
   function mapDispatchToProps(dispatch) {
      return {
         loginRequest: values => dispatch(loginRequest(values)),
      };
   }

// Sending values.toJS() to my redux-saga. 
   submit = values => {
      this.props.loginRequest(values.toJS());
   };

2) In reducer I do (should one use fromJS() here or not? According to redux docs you should):

const { fromJS } = require('immutable');
const state = fromJS({
  pages: {
    usersPage: {
      loading: false,
      isFetched: false,
      list: [],
    }
  }
});
function reducer(state, action) {
  switch(action.type) {
    case 'USERS_LOADED':
      return state
        .setIn(['usersPage', 'list'], action.payload) // fromJS() here or not?
        .setIn(['usersPage', 'isFetched'], true)
        .setIn(['usersPage', 'loading'], false)
        ;
    default:
      return state;
  }
}
export default reducer;

3) In my selector I do toJS() again:

const selectUser = state => state.get('user', initialState);
const makeSelectList= () =>
   createSelector(selectUser, userState => userState.getIn(['usersPage', 
'list']).toJS());

// Which I then use in my react component:
const mapStateToProps = createStructuredSelector({
   list: makeSelectList(),
});

So basically I wonder if that is a correct flow of convertion between js and immutable. Or can it be optimized in some way (less convertion steps)? Maybe the above is a non-optimal way of logic?

Best Regards

回答1:

  1. The saga--being redux middleware--can handle Immutable types directly, no need to use an expensive toJS call here

  2. Any point you're converting (e.g. set, setIn, update, etc) a plain JS non-simple type into the Immutable redux state tree, use fromJS to ensure a fully Immutable type Make entire state tree immutable

  3. IMHO, selectors (e.g. reselect)--by providing memoization after the initial retrieval--can be the most ideal place to utilize the expensive toJS calls, as in your example #3. I guess it really depends upon how much one dislikes using Immutable retrieval methods in their "container/smart" components, and/or creating a whole bunch of selectors to retrieve simple JS types from the redux state tree Use Immutable everywhere

To me there's the question of where to actually use the fromJS call, e.g. action creators, in the "container/smart" components dispatch or, in the reducer, e.g. react-boilerplate uses the fromJS call in the reducer.