The profile

In the project, we often encounter some problems, such as assigning an object to another object, how to achieve the modification of the assigned object and the original object unchanged; The common practice is copy, and copy is divided into shallowCopy and deepCopy; ShallowCopy is not available for deep-level objects, so the only way to avoid this is to use deepCopy, but deepCopy is a very performance intensive operation. For another example, when using react technology stack to do projects, we often need to manually determine whether some components need to be rerendered to reduce our cute and arrogant DOM operations. React provides shouldComponentUpdate hook function to determine whether the component tree needs to be rerendered. In the hook function, shallow comparison and deep comparison are used to determine whether the component tree needs to be rerendered. If it’s just a light comparison that only needs PureRender, what about a deep comparison? All this nonsense is about the advantages of immutable. It solves these problems, its shared structure is more powerful than it is, and it allows you to enjoy time travel at no cost to learn.

What is immutable

Immutable is supposed to be built by Lee Byron, a Facebook engineer, over the course of 3 years. It appears around the same time as React, but is not included in the React toolset by default (React provides a simplified Helper). Immutable, once created, returns a new object each time it is added, modified, or deleted. Immutable internal uses Structure Sharing to avoid the performance cost of each deepCopy. Each add, delete, and change only the current and parent nodes and return a new object.

It is said that Immutable allows the React application to be tens of times more efficient than Immutable. Assign or lodash can be used in a project to avoid the pitfalls of the original Object being modified, but they have many disadvantages. Object. Assign can only be copied one level deep, and you’ll find a full screen of object.assign. For a Virgo writer, this must not be tolerated; Immutable provides the IS method. Because Immutable internally uses Trie data structures, it only needs to compare hashCode or valueOf to avoid deep comparisons.

Immutable map and list are mutable, but they are not mutable. Immutable map and list are mutable, so they are mutable. Immutable map and list are mutable, so they are mutable. Alternatively, you can opt for a more simple seamless immutable code base that is much smaller, with a compressed download of 2K:

  • Convert JS to immutable:

    • Immutable. FromJs (obj) // Deep copy js objects or arrays to immutable
    • Immutable Map(obj)// Deep copy js objects to immutable
    • Immutable List(arr) // Deep copy js array to immutable array
  • immutable.List

    • Immutable.List([1,2])// initializes a List object
    • Immutablea.size // Find the length
    • IsList // Determines whether an array is mutable
    • ImmutableData. Get / / values
    • ImmutableA. Set / / set value
    • … . Other operations
  • immutable.Map

    • Immutable.Map({a: 1})// Initialize a Map object
    • Immutable map. isMap // Determines whether objects are mutable
    • ImmutableData. Get / / values
    • ImmutableA. Set / / set value
    • … . Other operations

React + Redux + IMmutable development process

When you use Immutable in React, you should avoid toJS operations because toJS and fromJS are performance consuming because they iterate over the entire data structure and create new objects to hold values. It is recommended that all projects use Immutable. Data is converted back to Immutable from service requests and then transferred to redux. It is only converted to native objects when submitting data and using third-party components or plug-ins that do not support IMmutable. Here is the development process that uses immutable.

State operations in React before immutable is used

// Copy the object before the operationlet newState = Object.assign({}, this.state.obj, {
	'a': 'test'}); // Copy the array before the operationlet newArr = [...arr, ...arr1];
Copy the code

Use immutable operations in React

This.state = Map(obj); // Initialize state by immutable; this.state = Map(obj); This.setstate (this.state.set(this.state.set());'a'.'test'));
Copy the code

How to use immutable when redux is used to manage state in a project? Redux built-in combineReducers and Reducer initialState are native objects. So it cannot be used with Immutable native; But you can either rewrite combineReducers or use Redux-ImmutableJS directly. This article shows how to use Redux-ImmutableJS.

Initialize the initialState

Following Redux’s workflow, we start by creating the Store. Redux’s createStore can pass multiple parameters, the first two being reducers and initialState

const initialState = immutable.Map({
    list: [],
    card: {
        id: ' ',
        title: ' ',
        desc: ' '}});Copy the code

reducer

Delete all previous Obecjt. assagin operations in reducer and convert them to immutable objects.

export default function list(state = initialState, action) {
      let card;
    switch (action.type) {
      case types.EDIT_ENTRY:
        let lists = state.get('list');
        lists = lists.push(action.newData.get('data'));
        card = action.newData.get('card'); 
        return state.set('list', lists).set('card', card);
      case types.VALUE_CHANGE:
        return state.set('card', action.card);
      case types.ADD:
        return state.set('card', action.card);
      default:
        returnstate; }}Copy the code

action

All objects in action are immutable. In order to distinguish between native objects, please do not use js native objects in some places and immutable objects in others. This tends to confuse and confuse the performance cost of immutable and native conversion.

export function editData() {
    let card = Map({
        id: ' ',
        title: ' ',
        desc: ' '
    });
    return { type: types.ADD, card };
  }
  
Copy the code

Access to the story

If you don’t pass initialState, redux-immutable will also help you build a global Map using the initial value of each sub-reducer as the global state during store initialization. Of course, this requires the default initial value of each of your child reducer to be immutable. We just have to introduce redux-immutable to use immutable in Redux,

import {
    combineReducers
  } from 'redux-immutable';
import list from './list/listRedux';
const rootReducer = combineReducers({
    list
  });

  export default rootReducer;
Copy the code

mapStateToProps

function mapStateToProps(state) {
  return {
    listMain: state.get('list')}; }export default connect(mapStateToProps)(Main);
Copy the code

conclusion

Immutable is not all items are suitable for use, in the business of simple data correlation is not complex and other conditions to use but increases the complexity of the project, through the above development process we should also see immutable intrusion or a tool, so if the project is initially considered on immutable can be; But consider the benefits and losses of using it in old projects.