A First Look at Seamless-Immutable in TodoMVC

When actions are triggered in Redux, a reducer is run that takes the previous state and an action, and returns the next state, like so:

(previousState, action) => newState

As I mentioned in a previous post, new state in Redux points at a new object reference. Immutability helps Redux efficiently re-render the app because we know easily when something has changed.

Therefore, a new object must be created whenever reducers generate a newState, without mutation.

In ES6, you would be able to create a copy with some edited data through Object.assign(). With ES7, you can also use the object spread operator, like so:

{ ...state, ...newState }

There are also two libraries that are popular for enforcing immutability in Redux: seamless-immutable and Immutable.js.

Immutable.js introduces shallowly immutable objects that are incompatible with the default javascript interfaces for objects and arrays, while seamless-immutable uses POJOs that are completely immutable without any magic. However, seamless-immutable doesn't do structural sharing.

What interests me in seamless-immutable rather than Immutable.js is maximizing javascript interoperability, so I gave it a whirl in a TodoMVC project.

Here are the changes in the todos.js reducers -- I'll go over each change one by one.

1) First, we import seamless-immutable into the file. Then we Immutable-ify the initial state of the application, like so:

Note that even the objects within the array will become immutable as well -- it's impossible to mix immutable and mutable objects. seamless-immutable will deeply convert everything to be immutable when wrapping an object.

2) We do something similar in the addTodo function:

3) In editTodo, we use the set() for seamless objects, which returns an Immutable Object with a single property set to the provided value:

4) We do the same thing for setting the complete flag.

5) Completing all todos is trivial:

My first impression is that integration of seamless-immutable seems pretty non-intrusive - interoperability allows us to continue to write pretty functional code. Also, performance is supposed to be pretty good because seamless-immutable will try its best to use existing nested objects rather than instantiate new ones, saving memory. I'll be posting more updates when integrating this library in a bigger project.

Here's the gist for the diffs you see above.

comments powered by Disqus