Explaining immutable values ​​in React

Explaining immutable values ​​in React

What are immutable values?

Functional programming means that the functions and expressions in the program can be like functions in mathematics. Given the input value, the output is certain. for example

let a = 1;
let b = a + 1;
=> a = 1 b = 2;

Variable b appears, and although the value of variable a is used, the value of a is not modified.

Let's look at the code in react that we are familiar with. If we initialize this.state = { count: 1 }

componentDidMount() {
    const newState = { ...state, count: 2 }; // { count: 2 }
    this.setState(newState);
}

Although we used this.state, we did not modify the reference address of this.state or directly modify the value of count. The same goes for this.props.

Why use immutable values?

React's official website gives three benefits:

  • Simplify complex functions

Immutability makes complex features easier to implement.

  • Tracking changes to data

If you modify the data directly, it will be difficult to track the changes. Tracking data changes requires that mutable objects can be compared with the versions before the change, so the entire object tree needs to be traversed once.

Tracking changes to immutable data is relatively easy. If we find that the object has become a new object, then we can say that the object has changed.

  • Determining when to re-render in React

The main advantage of immutability is that it helps us create pure components in React. We can easily determine if immutable data has changed, and therefore when to re-render a component.

React performance optimization is inseparable from immutable values

  • First of all, we all know that the shouldComponentUpdate hook function returns true by default, that is, as long as the parent component is updated, the child component must be updated.
  • shouldComponentUdpate can receive two parameters, nextProps and nextState. If we judge that this.props.xxx is equal to nextProps.xxx and this.state.xxx is equal to nextState.xxx, we can set the return value to false, indicating that the subcomponent does not need to be updated this time.
class CounterButton extends React.Component {
  constructor(props) {
    super(props);
    this.state = {count: 1};
  }

  shouldComponentUpdate(nextProps, nextState) {
    if (this.props.color !== nextProps.color) {
      return true;
    }
    if (this.state.count !== nextState.count) {
      return true;
    }
    return false;
  }

  render() {
    return (
      <button
        color={this.props.color}
        onClick={() => this.setState(state => ({count: state.count + 1}))}>
        Count: {this.state.count}
      </button>
    );
  }
}
  • React v15.3 adds a new PureComponent class that can perform shallow comparisons on props and state to reduce the number of executions of the render function, avoid unnecessary component rendering, and achieve performance optimization.
  • What is the principle of PureComponent?

We know that the variable types in JS are divided into basic types (number, string, boolean, undefined, null, symbol) and reference types (function, object, function). The values ​​of basic types are stored in stack memory, and the values ​​of reference types are stored in heap memory. The stack memory only stores references to heap memory. Shallow comparison is to compare only the data in the stack memory.

class App extends PureComponent {
  state = {
    items: [1, 2, 3]
  }
  handleClick = () => {
    const { items } = this.state;
    items.pop();
    this.setState({ items });
  }
  render() {
    return (
        <div>
            <ul>
                {this.state.items.map(i => <li key={i}>{i}</li>)}
            </ul>
            <button onClick={this.handleClick}>delete</button>
        </div>
    )
  }
}

The above example uses PureComponent and only changes the value in the items array without changing the reference address of the items. Therefore, it is considered that the items have not changed, and the render function will not be triggered, and the rendering of the component will not be triggered.

If you want to implement component updates, you can create a new array as follows and assign the address of the new array to items.

handleClick = () => {
    const { items } = this.state;
    items.pop();
    var newItem = [...items];
    this.setState({ item: newItem });
}
  • PureComponent helps us do a shallow comparison, so we should pay attention to the state as much as possible. If we need to reference nested references in the data structure, we can use Immutable.js.
  • What is Immutable

(1) Immutable is data that cannot be changed once created. (2) Any modification, addition, or deletion of an Immutable object will return a new Immutable object. (3) The principle of Immutable implementation is Persistent Data Structure, that is, when permanent data creates new data, it is necessary to ensure that the old data is available and unchanged at the same time. (4) At the same time, in order to avoid the performance loss caused by deepCopy copying all nodes, Immutable uses structural sharing, that is, if the object tree node changes, only the node and the parent node affected by it are modified, and other nodes are shared.

Finally, if you want to do a shallow comparison at the component level, you can use the React.memo() function

Summarize

In fact, the third and most important advantage of immutability mentioned on the official website is that immutability can help us use PureComponent in React. We can easily determine if data has changed and when a component needs to be re-rendered.

If we change the value of state, shouldComponentUpdate obtains the current state and nextState, or the values ​​compared by props and nextProps are exactly the same, false will be returned. Even if we perform a setState operation, the UI will not be updated.

PureComponent is best used with Immutable.js to achieve performance optimization.

Combined with React.memo to avoid unnecessary component updates and rendering.

The above is a detailed explanation of immutable values ​​in React. For more information about immutable values ​​in React, please pay attention to other related articles on 123WORDPRESS.COM!

You may also be interested in:
  • React example of how to get the value of the input box
  • React ant Design manually sets the value of the form
  • React uses antd form assignment to modify the operation of the pop-up box
  • Use antd's form component in the react project to dynamically set the value of the input box
  • React PropTypes validation passed value operation example
  • Detailed explanation of the relationship between React component value passing
  • Three ways to pass values ​​in react components
  • Detailed explanation of value transfer between Vue and React components
  • React method of passing values ​​between parent and child components
  • Detailed explanation of the role and use of React key values
  • React method of passing values ​​between parent and child components
  • React child component transfers value to parent component
  • Example of how react-router implements jump value transfer

<<:  Detailed explanation of MySQL batch SQL insert performance optimization

>>:  Solution to the problem of information loss with "_" in header when using Nginx proxy

Recommend

Why MySQL can ignore time zone issues when using timestamp?

I have always wondered why the MySQL database tim...

How to implement rounded corners with CSS3 using JS

I found an example when I was looking for a way t...

How are Vue components parsed and rendered?

Preface This article will explain how Vue compone...

Super simple implementation of Docker to build a personal blog system

Install Docker Update the yum package to the late...

MySQL solution for creating horizontal histogram

Preface Histogram is a basic statistical informat...

Linux kernel device driver memory management notes

/********************** * Linux memory management...

Three ways to forward linux ssh port

ssh is one of the two command line tools I use mo...

Detailed explanation of commands to view linux files

How to view linux files Command to view file cont...

Install Python 3.6 on Linux and avoid pitfalls

Installation of Python 3 1. Install dependent env...

MySQL multi-table join query example explanation

In actual projects, there are relationships betwe...

Using Docker run options to override settings in the Dockerfile

Usually, we first define the Dockerfile file, and...