Editor’s recommendation:

This article helps you understand what is immutable from 0, and what function it has, under what background arises.

The most important thing is that it is one of the commonly used technologies in our daily development, and the use of Immutable in conjunction with React can give us developers how much convenience, this article will discuss in turn.

Background that appears immutable

In our daily development, I believe we have encountered a problem, that is, how to return the data back end, deep copy, and then for our own use?

If you have used React framework to develop projects, you must remember that the Reducer in Redux is designed based on pure functions. If the state data (objects or arrays) is required to be returned, you need to make a deep copy first (to prevent the old state from being affected), and then operate on the copied values according to your own development requirements.

Here’s an example:

let list = [

  { name'house'.age18}

]



let newList = [...list];

newList[0].name = "xiaoming";



console.log(list[0].name); // "xiaoming"

Copy the code

The reason for this is that the expansion operator […list] in ES6 is a shallow copy, meaning that only the first level of the object or array is copied.

In the above example, you can see that the shallow copy of the expansion operator only copies the address of the inner reference type. When the reference address is found through the index and changed, it changes the original array of the list itself.

Of course, some friend can think: when access to the object attribute value, attribute values and recursive comparison, so that to reach deep contrast effect, but think of an extreme case, is ten thousand article in properties, only the last one attribute has changed, then we will have ten thousand properties are traversal. This is a huge waste of performance.

To get back to the essence of the problem, whether we use shallow comparisons directly or deep comparisons, what we ultimately want to know is whether or not the properties in the original object have changed.

Under such conditions, immutable data arises.

What is immutable data?

Immutable a persistent data structure that uses structure sharing to return an entirely new object when part of it is modified, and the original nodes are directly shared.

Each time an immutable object is modified, a new immutable object is created. The operation on the new object does not affect the data in the original object.

To be specific, immutable data adopts the structure of multiple cross trees. Whenever a node is changed, it and all its related parent nodes are updated.

Here’s a GIF to simulate the process:

Immutable modifies the node update reference process

Isn’t it! Only the parent node is updated, which is much better than directly comparing all the properties, and the update returns a new reference, which is aware of changes even in shallow comparisons.

Therefore, immutable is an efficient way to update data structures and to communicate with the existing PureComponent (Memo) in React. It is an excellent solution to improve React rendering performance.

Immutable objects are mutable objects that are not mutable. They are mutable objects that are not mutable. They are mutable objects that are not mutable.

Immutable is a way to optimize performance

Immutable is implemented by persisting data structures, that is, using old data to create new data, to ensure that the old data at the same time available and unchanged. And to avoid the performance cost of deepCopy copying all the nodes.

Immutable uses structural sharing, which means that if a node in an object tree changes, only that node and its affected parent are modified, and all other nodes are shared.

Where is immutable performance optimized

Immutable optimization

In combination with the React PureComponent(Memo), we know that the PureComponent internally helps us compare the new props to the old props and the new state to the old state. If the values are equal or the objects contain the same properties and the property values are equal, ShouldComponentUpdate returns true or false to determine if the Render function should be rendered again.

When we use the immutable third library, we can make a deep copy of an object a. When we change the value of a’s SELECT property to b, it does not affect a, and b’s SELECT property changes to the new value.

If the select attribute is used for one component, shouldComponentUpdate should return true. If the filter attribute is used for another component, shouldComponentUpdate should return false. If the filter attribute is used for another component, shouldComponentUpdate should return false. As a result, this component avoids duplicate diFF algorithm comparisons and greatly improves performance optimization in React.

With such a good third-party library, let’s take a look at its basic usage:

A common type is immutable

(1) Map() package object

const { Map } = require('immutable'); 

const map1 = Map({ a1.b2.c3 }); 

const map2 = map1.set('b'.50);



console.log(map1.get('b')); / / 2

console.log(map2.get('b')); / / 50

Copy the code

(2) List() wraps the array

const { List } = require('immutable');



const list1 = List([ 1.2 ]); 

const list2 = list1.push(3.4.5);  / / [1, 2, 3, 4, 5]

const list3 = list2.unshift(0);    / /,1,2,3,4,5 [0]

const list4 = list1.concat(list2, list3); / /,2,3,4,5,0,1,2,3,4,5 [1]



Push, set, unshift, or splice return a new immutable object

Copy the code

(3) the merge () connection objects | concat () array

const { Map, List } = require('immutable');



const map1 = Map({ a1.b2.c3.d4 });

const map2 = Map({ c10.a20.t30 });

const obj = { d100.o200.g300 };



const map3 = map1.merge(map2, obj);

// Map { a: 20, b: 2, c: 10, d: 100, t: 30, o: 200, g: 300 }



const list1 = List([ 1.2.3 ]);

const list2 = List([ 4.5.6 ]);



const list3 = list1.concat(list2, array);

// List [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]

Copy the code

ToJS () converts immutable objects toJS objects

const { Map, List } = require('immutable');



const deep = Map({ a1.b2.c: List([ 3.4.5])});

console.log(deep.toObject());   // { a: 1, b: 2, c: List [ 3, 4, 5 ] }

console.log(deep.toArray());    // [ 1, 2, List [ 3, 4, 5 ] ]

console.log(deep.toJS());       // { a: 1, b: 2, c: [ 3, 4, 5 ] }

JSON.stringify(deep);           / / '{" a ": 1," b ": 2," c ": [three, four, five]}'

Copy the code

Converts js objects fromJS to immutable objects

const { fromJS } = require('immutable');



const nested = fromJS({ a: { b: { c: [ 3.4.5]}}});

// Map { a: Map { b: Map { c: List [ 3, 4, 5 ] } } }



const nested2 = nested.mergeDeep({ a: { b: { d6}}});

// Map { a: Map { b: Map { c: List [ 3, 4, 5 ], d: 6 } } }



console.log(nested2.getIn([ 'a'.'b'.'d' ])); / / 6

GetIn (["a","b","c"]])



// setIn sets a new value

const nested3 = nested2.setIn([ 'a'.'b'.'d']."kerwin");

// Map { a: Map { b: Map { c: List [ 3, 4, 5 ], d: "kerwin" } } }



// The updateIn callback is updated

const nested3 = nested2.updateIn([ 'a'.'b'.'d' ], value => value + 1);

console.log(nested3);

// Map { a: Map { b: Map { c: List [ 3, 4, 5 ], d: 7 } } }



const nested4 = nested3.updateIn([ 'a'.'b'.'c' ], list => list.push(6));

// Map { a: Map { b: Map { c: List [ 3, 4, 5, 6 ], d: 7 } } }

Copy the code

Relatively complete immutable some common methods, are summarized here for you, you can master the project after commonly used.

Generality of immutable

Immutable can be used in any framework that introduces third-party libraries.

Here are some simple usage cases of Reducer in my React development:

Immutable +Redux development mode

Case 1: Immutable is not used

The following code is dangerous and is not recommended because an error will occur when the types in the newStateList are more complex (including reference types) and the newStateList needs to be modified, because [… XXX,… XXX] is a shallow copy that affects the original state.

Case 2: Use immutable

The old prevState passes through the store to immutable object, after the deep copy of the object, and then modifies the operation, does not affect the original state, and finally through toJS() to convert toJS objects

This paper summarizes

Immutable does not have deep comparisons because they are expensive.

Immutable data is modified by calling a set method that only modifies the local node and all related upper-level nodes above it, ensuring that different references are made and data is updated. More importantly, it improves performance by avoiding comparisons of irrelevant data.

Read three things ❤

If you found this post helpful, I’d like to invite you to do three small favors for me:

  1. Like it, retweet it, you got it"Looking at"Is what drives me to create.
  2. Follow public Account"Front End Time House"To share original knowledge irregularly.
  3. In the meantime, look forward to a follow-up article at ing🚀