Skip to content

Contact sales

By filling out this form and clicking submit, you acknowledge our privacy policy.

Push or Add with the Immutability Operation in Redux and Immutable.js

This guide will help you learn about the immutability operation with Redux, which you can use to push or add a new item to the state.

Oct 29, 2020 • 5 Minute Read

Introduction

React uses Redux as a state management library, which creates the global state object with the store's help, and all child components can subscribe and use the piece of the global state as a prop. The Redux state is immutable. Once new action triggers, the new state values get reflected. To improve immutability, a library such as redux-immutable can be used. This will also ensure the highest possible performance by implementing immutability.

This guide will help you learn about the immutability operation with Redux, which you can use to push or add a new item to the state.

Why are Redux and Immutable.js Used?

Immutability is a crucial aspect of app performance. To manage immutability across the app, along with the Redux, redux-immutable is used. When an action is dispatched from a component, the associated network call triggers and returns the response. And then the same response should get added as a new object into the existing data structure.

By following the complete Redux cycle, the app ensures that no state object is mutated accidentally, and the new state object gets returned from the store.

How to Push or Add Using redux-immutable

To push or add new objects into the existing data structure, first install the given libraries.

      npm install immutable
npm install redux-immutable
    

After installing both libraries, you will be able to implement an immutable collection.

The redux-immutable library, used along with the library immutable as a supporting library, creates the instance of Immutable.Collection.

Open store.js file and paste the below lines of code.

      import { createStore, applyMiddleware } from "redux";
import thunk from "redux-thunk";
import { createLogger } from "redux-logger";
// Used immutable
import Immutable from "immutable";
// Used redux-immutable
import { combineReducers } from "redux-immutable";
import reducers from "../reducers";

const logger = createLogger();

const reducer = combineReducers(reducers);

const store = createStore(
  reducer,
  Immutable.Map({}),
  applyMiddleware(thunk, logger)
);

export default store;
    

In the above file of the store configuration, the store creation done is via the function combineReducer(), which is imported from redux- immutable.

      const reducer = combineReducers(reducers);
    

And the combineReducers() function accepts one argument as a collection of reducer, i.e., root reducer representing the single store state object. Another statement to note is the initialization of the immutable collection.

      Immutable.Map({})
    

The above statement initializes the state with the state's empty initial value, which is, by default, immutable. After configuring the store, the next step is to create the reducer and push or add the object into the state.

Todo.js (Reducer)

      import _ from "lodash";
import { createReducer } from "redux-create-reducer";
import Immutable from "immutable";

const initialState = Immutable.fromJS([
    {
        done: true,
        id: _.uniqueId(),
        name: "TODO 1"
    },
    {
        done: false,
        id: _.uniqueId(),
        name: "TODO 2"
    }
]);

const ADD_TODO = (domain, action) => {
    return domain.push(
        Immutable.Map({
            done: false,
            id: _.uniqueId(),
            name: action.data.name
        })
    );
};

export default createReducer(initialState, {
    ADD_TODO
});
    

In the above reducer file, there is one const called initialState containing the list of initial todos, but the object is surrounded by the immutable initialization function, as shown below.

      const initialState = Immutable.fromJS([
    {
        done: true,
        id: _.uniqueId(),
        name: "TODO 1"
    },
    {
        done: false,
        id: _.uniqueId(),
        name: "TODO 2"
    }
]);
    

The function fromJS() maps the objects as immutable objects, and you can add or push a new object as demonstrated below.

      return domain.push(
        Immutable.Map({
            done: false,
            id: _.uniqueId(),
            name: action.data.name
        })
);
    

domain.push() is used to add new todo items into the existing todo object, which is the opposite of ordinary object assignment. And the final step is to assign the store to the app, as shown below.

Index.js

      import React from "react";
import { render } from "react-dom";
import { Provider } from "react-redux";
import App from "./components/App";
// Store with immutability
import store from "./store";

render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById("root")
);
    

The created store is imported into the React app's index and assigned to the provider so that once you dispatch the action, the new object is added to the global state object.

Conclusion

Immutability is one solution that can help overcome app performance issues by following immutability best practices instead of using the ordinary way of mutating a Redux state object.

You can use an immutable library, and specifically for React, redux-immutable is one of the best choices to implement immutability in no time. I hope this guide helps you apply the best possible immutability tactics.