born2net
born2net

Reputation: 24973

Why should objects in Redux be immutable?

Why should objects in Redux be immutable? I know that some frameworks such as Angular2 will use onPush and can take advantage of immutability to compare states of views for faster rendering, but I am wondering if there are other reasons as Redux is framework agnostic and yet it mentions within its own docs to use immutability (regardless of the framework).

Appreciate any feedback.

Upvotes: 52

Views: 22646

Answers (6)

beliha
beliha

Reputation: 322

Honestly, I have been using react for a while and I just think it's one of those things where every programmer just repeats what they are being told about the benefits of immutability, yet no one really understands or believes it.

All the reasons I've heard over the past 8 years about the benefits of immutability aren't convinving, and sound like 'preference' and 'paradigm' reasons to me, rather than actually being beneficial. I believe it's an outdated concept. My biggest proof of this is that both Vuex and Pinia (vue.js's state managements systems) are mutable, and they have none of the issues Redux claim it would have were it mutable.

So I would say it's just preference, very much in the vein of OOP vs Functional programming.

Upvotes: 0

alithecodeguy
alithecodeguy

Reputation: 139

Based on the official docs :

There are several reasons why you must not mutate state in Redux:

  • It causes bugs, such as the UI not updating properly to show the latest values
  • It makes it harder to understand why and how the state has been updated
  • It makes it harder to write tests
  • It breaks the ability to use "time-travel debugging" correctly
  • It goes against the intended spirit and usage patterns for Redux

Reudx official docs

Upvotes: 0

Himanshu Dhingra
Himanshu Dhingra

Reputation: 367

The main reason Redux is using immutability is that it doesn't have to traverse an object tree to check for the changes in every key value. Instead, it will only check the object's reference is changed or not in order to update DOM on state change.

Upvotes: 9

Andrea Casaccia
Andrea Casaccia

Reputation: 4971

The following benefits of immutability are mentioned in Redux documentation:

  • Both Redux and React-Redux employ shallow equality checking. In particular:
    • Redux's combineReducers utility shallowly checks for reference changes caused by the reducers that it calls.
    • React-Redux's connect method generates components that shallowly check reference changes to the root state, and the return values from the mapStateToProps function to see if the wrapped components actually need to re-render. Such shallow checking requires immutability to function correctly.
  • Immutable data management ultimately makes data handling safer.
  • Time-travel debugging requires that reducers be pure functions with no side effects, so that you can correctly jump between different states.

Upvotes: 16

Ashley Coolman
Ashley Coolman

Reputation: 11585

Redux is a small library that represents state as (immutable) objects. And new states by passing the current state through pure functions to create an entirely new object/application states.

If your eyes-glazed over there don't worry. To sum up, Redux does not represent changes in your application's state by modifying objects ( as you would with object-oriented paradigms). Instead state changes are represented as the difference between the input object and the output object (var output = reducer(input)). If you mutate either input or output you invalidate the state.

To sum up another way, immutability is a requirement of Redux because Redux represents your application state as "frozen object snapshots". With these discrete snapshots, you can save your state, or reverse state, and generally have more "accounting" for all state changes.

State of your app is only changed by a category of pure functions called reducers. Reducers have 2 important properties:

  1. They never mutate, returning newly built objects: This allows reasoning about input + output without side-effects
  2. Their signature is always function name(state, action) {}, so it makes it easy to compose them:

Assume the state looks like this:

    var theState = {
      _2ndLevel: {
        count: 0
      }
    }

We want to increment the count, so we make these reducers

const INCR_2ND_LEVEL_COUNT = 'incr2NdLevelCount';

function _2ndlevel (state, action) {
    switch (action.type) {
        case INCR_2ND_LEVEL_COUNT:
            var newState = Objectd.assign({}, state);
            newState.count++
            return newState;
        }
    }

function topLevel (state, action) {
    switch (action.type) {
        case INCR_2ND_LEVEL_COUNT:
            return Object.assign(
                {}, 
                {_2ndLevel: _2ndlevel(state._2ndlevel, action)}
            );
    }
}

Note the use of Object.assign({}, ...) to create an entirely new objects in each reducer:

Assuming we have wired up Redux to these reducers, then if we use Redux's event system to trigger a state change ...

    dispatch({type: INCR_2ND_LEVEL_COUNT})

...Redux will call:

    theNewState = topLevel(theState, action);

NOTE: action is from dispatch()

Now theNewState is an entirely new object.

Note: You can enforce immutability with a library (or new language features), or just be careful to not mutate anything :D

For a deeper look, I highly recommend you checkout this video by Dan Abramov (the creator). It should answer any lingering questions you have.

Upvotes: 48

zloctb
zloctb

Reputation: 11184

Greate article https://medium.cobeisfresh.com/how-redux-can-make-you-a-better-developer-30a094d5e3ec

Along with immutable data, pure functions are one of the core concepts of functional programming

Upvotes: 1

Related Questions