Last Updated: September 30, 2021
·
7.179K
· Evgenia Karunus

Updating your Redux app to use ImmutableJS

We can use immutable-js multiple ways with Redux. It depends on whether we want our root state to be immutable or not.

If we choose the Hard way, we may have some problems with libs such as redux-form down the road (solvable though).

There is an issue discussing if we need the Hard way at all: https://github.com/gajus/redux-immutable/issues/32.

Simple way

  1. npm install immutable --save
  2. And now we can convert one reducer at a time:

    const reducer = (courses = initialState, action) => {
        courses = Immutable.fromJS(courses) // converting courses to an immutable object
        if (action.type == 'FETCHING_COURSES_SUCCESS') {
            return courses
                .set('status', 'success')
                .set('error', null)
                .set('items', action.items)
                .toJS() // returning usual JS object
        }
    };

Hard way

  1. npm install immutable redux-immutable --save

  2. Import your combineReducers function from newly installed redux-immutable, instead of redux

    import { combineReducers } from 'redux-immutable';
  3. And now we can start changing one reducer at a time.

    Make initial state an immutable-js object.

    Now you can use immuable-js methods in your reducers, such as get and set.

    import Immutable from 'immutable';
    const initialState = Immutable.fromJS({
        status: null,
        error: null,
        items: []
    });
    const coursesReducer = (courses = initialState, action) => {
        if (action.type == 'FETCHING_COURSES_SUCCESS') {
            return courses
                .set('status', 'success')
                .set('error', null)
                .set('items', action.items)
        }
    };
  4. Since state is an immutable-js object now, we need to translate it to something our react components will understand. That is, plain Js.

    const mapStateToProps = (state) => {
      return {
        courseItems: state.toJS().courses.items
      }
    };