MyPage is a personalized page based on your interests.The page is customized to help you to find content that matters you the most.

I'm not curious

Immutability in JavaScript using Redux

Published on 02 February 17

In an ever growing ecosystem of rich and complicated JavaScript applications, there’s more state to be managed than ever before: the current user, the list of posts loaded, etc.

Any set of data that needs a history of events can be considered stateful. Managing state can be hard and error prone, but working with immutable data (rather than mutable) and certain supporting technologies- namely Redux, for the purposes of this article- can help significantly.

Immutable data has restrictions, namely that it can’t be changed once it’s created, but it also has many benefits, particularly in reference versus value equality, which can greatly speed up applications that rely on frequently comparing data (checking if something needs to update, for example).

Using immutable states allows us to write code that can quickly tell if the state has changed, without needing to do a recursive comparison on the data, which is usually much, much faster.

This article will cover the practical applications of Redux when managing state through action creators, pure functions, composed reducers, impure actions with Redux-saga and Redux Thunk and, finally, use of Redux with React. That said, there are a lot of alternatives to Redux, such as MobX, Relay, and Flux based libraries.
Immutability in JavaScript using Redux - Image 1
Why Redux?

The key aspect that separates Redux from most other state containers such as MobX, Relay, and most other Flux based implementations is that Redux has a single state that can only be modified via actions (plain JavaScript objects), which are dispatched to the Redux store. Most other data stores have the state contained in React components themselves, allow you to have multiple stores and/or use mutable state.

This in turn causes the store’s reducer, a pure function that operates on immutable data, to execute and potentially update the state. This process enforces unidirectional data flow, which is easier to understand and more deterministic.
Immutability in JavaScript using Redux - Image 2
Since Redux reducers are pure functions operating on immutable data, they always produce the same output given the same input, making them easy to test. Here’s an example of a reducer:
Immutability in JavaScript using Redux - Image 3

Dealing in pure functions allows Redux to easily support many use cases that are generally not easily done with mutative state, such as:

  • Time travel (Going back in time to a previous state)
  • Logging (Track every single action to figure out what caused a mutation in the store)
  • Collaborative environments (Such as GoogleDocs, where actions are plain JavaScript objects and can be serialized, sent over the wire, and replayed on another machine)
  • Easy bug reporting (Just send the list of actions dispatched, and replay them to get the exact same state)
  • Optimized rendering (At least in frameworks that render virtual DOM as a function of state, such as React: due to immutability, you can easily tell if something has changed by comparing references, as opposed to recursively comparing the objects)
  • Easily test your reducers, as pure functions can easily be unit tested
Action Creators

Redux’s action creators help in keeping code clean and testable. Remember that actions in Redux are nothing more than plain JavaScript objects describing a mutation that should occur. That being said, writing out the same objects over and over again is repetitive and error prone.

An action creator in Redux is simply a helper function that returns a plain JavaScript object describing a mutation. This helps reduce repetitive code, and keeps all your actions in one place:
Immutability in JavaScript using Redux - Image 4
Using Redux with Immutable Libraries

While the very nature of reducers and actions make them easy to test, without an immutability helper library, there’s nothing protecting you from mutating objects, meaning the tests for all your reducers have to be particularly robust.

Consider the following code example of a problem you’ll run into without a library to protect you:
Immutability in JavaScript using Redux - Image 5

In this code example, time travel will be broken as the previous state will now be the same as the current state, pure components may potentially not update (or re-render) as the reference to the state has not changed even though the data it contains has changed, and mutations are a lot harder to reason through.

Without an immutability library, we lose all the benefits that Redux provides. It’s therefore highly recommended to use an immutability helper library, such as immutable.js or seamless-immutable, especially when working in a large team with multiple hands touching code.

Regardless of which library you use, Redux will behave the same. Let’s compare the pros and cons of both so that you’re able to pick whichever one is best suited for your use case:

Immutable.js is a library, built by Facebook, with a more functional style take on data structures, such as Maps, Lists, Sets, and Sequences. Its library of immutable persistent data structures perform the least amount of copying possible in between different states.


  • Structural sharing
  • More efficient at updates
  • More memory efficient
  • Has a suite of helper methods to manage updates


  • Does not work seamlessly with existing JS libraries (i.e lodash, ramda)
  • Requires conversion to and from (toJS / fromJS), especially during hydration / dehydration and rendering

Seamless-immutable is a library for immutable data that is backwards compatible all the way to ES5.

It’s based on ES5 property definition functions, such as defineProperty(..) to disable mutations on objects. As such, it is fully compatible with existing libraries like lodash and Ramda. It can also be disabled in production builds, providing a potentially significant performance gain.


  • Works seamlessly with existing JS libraries (i.e lodash, ramda)
  • No extra code needed to support conversion
  • Checks can be disabled in production builds, increasing performance


  • No structural sharing - objects / arrays are shallow-copied, makes it slower for large data sets
  • Not as memory efficient
Redux and Multiple Reducers
Another useful feature of Redux is the ability to compose reducers together.This allows you to create much more complicated applications, and in an application of any appreciable size, you will inevitably have multiple types of state (current user, the list of posts loaded, etc). Redux supports (and encourages) this use case by naturally providing the function combineReducers:
Immutability in JavaScript using Redux - Image 6
With the above code, you can have a component that relies on the currentUser and another component that relies on the postsList. This also improves performance as any single component will only be subscribing to whatever branch(es) of the tree concerns them.
Impure Actions in Redux

By default, you can only dispatch plain JavaScript objects to Redux. With middleware, however, Redux can support impure actions such as getting the current time, performing a network request, writing a file to disk, and so on.

‘Middleware’ is the term used for functions that can intercept actions being dispatched. Once intercepted, it can do things like transform the action or dispatch an asynchronous action, much like middleware in other frameworks (such as Express.js).

Two very common middleware libraries are Redux Thunk and Redux-saga. Redux Thunk is written in an imperative style, while Redux-saga is written in a functional style. Let’s compare both.
Redux Thunk
Redux Thunk supports impure actions within Redux by using thunks, functions that return other chain-able functions. To use Redux-Thunk, you must first mount the Redux Thunk middleware to the store:
Immutability in JavaScript using Redux - Image 7
Now we can perform impure actions (such as performing an API call) by dispatching a thunk to the Redux store:
Immutability in JavaScript using Redux - Image 8
It’s important to note that using thunks can make your code hard to test and makes it harder to reason through code flow.

Redux-saga supports impure actions through an ES6 (ES2015) feature called generators and a library of functional / pure helpers. The great thing about generators is that they can be resumed and paused, and their API contract makes them extremely easy to test.

Let’s see how we can improve readability and testability of the previous thunk method using sagas!

First, let’s mount the Redux-saga middleware to our store:
Immutability in JavaScript using Redux - Image 9

Note that the run(..) function must be called with the saga for it to begin executing.

Now let’s create our saga:
Immutability in JavaScript using Redux - Image 10

We defined two generator functions, one that fetches the users list and the rootSaga. Notice that we didn’t call api.fetchUsers directly but instead yielded it in a call object. This is because Redux-saga intercepts the call object and executes the function contained within to create a pure environment (as far as your generators are concerned).

rootSaga yields a single call to a function called takeEvery, which takes every action dispatched with a type of USERS_FETCH and calls the fetchUsers saga with the action it took. As we can see, this creates a very predictable side effect model for Redux, which makes it easy to test!

Testing Sagas

Let’s see how generators make our sagas easy to test. We’ll be using mocha in this part to run our unit tests and chai for assertions.

Because sagas yield plain JavaScript objects and are run within a generator, we can easily test that they perform the right behavior without any mocks at all! Keep in mind that call , take , put, etc are just plain JavaScript objects that are intercepted by the Redux-saga middleware.
Immutability in JavaScript using Redux - Image 11
Working with React

While Redux isn’t tied to any specific companion library, it works especially well with React.js since React components are pure functions that take a state as input and produce a virtual DOM as output.

React-Redux is a helper library for React and Redux that eliminates most of the hard work connecting the two. To most effectively use React-Redux, let’s go over the notion of presentational components and container components.

Presentational components describe how things should look visually, depending solely on their props to render; they invoke callbacks from props to dispatch actions. They’re written by hand, completely pure, and are not tied to state management systems like Redux.

Container components, on the other hand, describe how things should function, are aware of Redux, dispatch Redux actions directly to perform mutations and are generally generated by React-Redux. They are often paired with a presentational component, providing its props.
Immutability in JavaScript using Redux - Image 12
Let’s write a presentational component and connect it to Redux via React-Redux:
Immutability in JavaScript using Redux - Image 13
Note that this is a dumb component that completely relies on its props to function. This is great, because it makes the React component easy to test and easy to compose. Let’s look at how to connect this component to Redux now, but first let’s cover what a Higher Order Component is.
Higher Order Components

React-Redux provides a helper function called connect( .. ) that creates a higher order component from a dumb React component that is aware of Redux.

React emphasizes extensibility and re-usability through composition, which is when you wrap components in other components. Wrapping these components can change their behavior or add new functionality. Let’s see how we can create a higher order component out of our presentational component that is aware of Redux - a container component.

Here’s how you do it:
Immutability in JavaScript using Redux - Image 14

Note that we defined two functions, mapStateToProps and mapDispatchToProps .

mapStateToProps is a pure function of (state: Object) that returns an object computed from the Redux state. This object will be merged with the props passed to the wrapped component. This is also known as a selector, since it selects parts of the Redux state to be merged into the component’s props.

mapDispatchToProps is also a pure function, but one of (dispatch: (Action) => void) that returns an object computed from the Redux dispatch function. This object will likewise be merged with the props passed to the wrapped component.

Now to use our container component we must use the Provider component in React-Redux to tell the container component what store to use:
Immutability in JavaScript using Redux - Image 15
The Provider component propagates the store down to any child components who subscribe to the Redux store, keeping everything in one place and reducing points of error or mutation!
Build Code Confidence with Redux
With this newfound knowledge of Redux, its numerous supporting libraries and its framework connection with React.js, you can easily limit the number of mutations in your application through state control. Strong state control, in turn, lets you you move faster and create a solid code base with more confidence.
Via Toptal.
This blog is listed under Development & Implementations Community

Related Posts:




View Comments (3)
Post a Comment

Please notify me the replies via email.

  • We hope the conversations that take place on will be constructive and thought-provoking.
  • To ensure the quality of the discussion, our moderators may review/edit the comments for clarity and relevance.
  • Comments that are promotional, mean-spirited, or off-topic may be deleted per the moderators' judgment.
  1. 04 July 19

    Hey there!!! Great Article and also i know a company which have a great team of dedicated and professional react js developers. Check out this: React JS

  2. 04 July 19

    Hey there!!! Great Article and also i know a company which have a great team of dedicated and professional react js developers. Check out this: React JS

You may also be interested in
Awards & Accolades for MyTechLogy
Winner of
Top 100 Asia
Finalist at SiTF Awards 2014 under the category Best Social & Community Product
Finalist at HR Vendor of the Year 2015 Awards under the category Best Learning Management System
Finalist at HR Vendor of the Year 2015 Awards under the category Best Talent Management Software
Hidden Image Url