Skip to content

Streamlines use of Immutable.js with Redux reducers.

License

Notifications You must be signed in to change notification settings

Johnius/redux-immutable

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

52 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

redux-immutable

Travis build status NPM version

This package provides a single function combineReducers, which implements:

Refer to https://github.com/gajus/redux-immutable-examples for an example of a Redux app using redux-immutable.

Initial State

You can provide Redux createStore with the initial state using Immutable data, e.g.

import {
    createStore
} from 'redux';

import {
    combineReducers
} from 'redux-immutable';

import Immutable from 'immutable';

import * as reducers from './reducers';

let reducer,
    store,
    state;

reducer = combineReducers(reducers);

state = {};

state.countries = [
    'IT',
    'JP',
    'DE'
];

state = Immutable.fromJS(state);

// Required to construct domain state.
state = reducer(state);
store = createStore(reducer, state);

export default store;

A domain reducer can initialize the state of the domain using CONSTRUCT method, e.g.

export default {
    // Implementing country domain reducers using arrow function syntax.
    countries: {
        CONSTRUCT: () => {
            return Immutable.List([
                'IT',
                'JP',
                'DE'
            ]);
        }
        ADD_COUNTRY: (domain, action) => {
            return domain.push(action.country);
        },
        REMOVE_COUNTRY: (domain, action) => {
            return domain.delete(domain.indexOf(action.country));
        }
    }
}

Unpacking Immutable State

redux-immutable combineReducers turns state into Immutable data. Therefore, when you request the store state you will get an instance of Immutable.Iterable:

let state;

state = store.getState();

console.log(Immutable.Iterable.isIterable(state));
// true

You can convert the entire state to a raw JavaScript object using Immutable.js toJS() function:

state = store.getState().toJS();

The disadvantage of this method is that it will create a new JavaScript object every time it is called:

console.log(state.toJS() === state.toJS());
// false

Because shallow comparison says that new state is different from the previous state you cannot take advantage of PureRenderMixin or an equivalent logic that manages shouldComponentUpdate using shallow object comparison.

For the above reason, you should refrain from converting state or parts of the state to raw JavaScript object.

Example

store.js

import {
    createStore
} from 'redux';

import {
    combineReducers
} from 'redux-immutable';

import Immutable from 'immutable';

import * as reducers from './reducers';

let app,
    store,
    state;

state = {};

state.countries = [
    'IT',
    'JP',
    'DE'
];

state.cities = [
    'Rome',
    'Tokyo',
    'Berlin'
];

state.user = {
    names: [
        'Gajus',
        'Kuizinas'
    ]
};

state = Immutable.fromJS(state);

app = combineReducers(reducers);
store = createStore(app, state);

export default store;

reducers.js

/**
 * @param {Immutable} state
 * @param {Object} action
 * @param {String} action.type
 * @param {Number} action.id
 */
export default {
    // Implementing country domain reducers using arrow function syntax.
    countries: {
        ADD_COUNTRY: (domain, action) => domain.push(action.country),
        REMOVE_COUNTRY: (domain, action) => domain.delete(domain.indexOf(action.country))
    },
    // Implementing city domain reducers using object method syntax.
    cities: {
        ADD_CITY (domain, action) {
            return domain.push(action.city);
        }
        REMOVE_CITY (domain, action) {
            return domain.delete(domain.indexOf(action.city));
        }
    },
    // Implement a sub-domain reducer map.
    user: {
        names: {
            ADD_NAME (domain, action) {
                return domain.push(action.name);
            }
            REMOVE_NAME (domain, action) {
                return domain.delete(domain.indexOf(action.name));
            }
        }
    }
};

About

Streamlines use of Immutable.js with Redux reducers.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • JavaScript 100.0%