Detailed explanation of the use of state, the three major attributes of React

Data is needed in many places in React, which is called state in React. We need a special method to manage state, so state-related was born. State should be required to have two basic functions. First, it can store a certain value so that it can be used by React. Second, it can be monitored and re-rendered by React when it changes. Here we introduce how to write state in class and function components respectively:

class component

 

class ClassComponent extends React.Component{

    constructor(props){

        super(props)

    } //可写可不写

    render(){

        return (

            //这里面可以写jsx语法

        )

    }

}

SetState is generally used to change the state. In it, you can directly pass an object to be changed, or you can pass a callback function. Note that if the object is passed in at this time, React only makes a shallow copy, not a deep copy. Copy, so if other objects in the object have been changed at this time, React cannot know and render. This method essentially passes in a new value and overwrites the original value. If this value is the same as the original value, React will not render.

Why is React so troublesome and can't modify the value directly? Because in React, there is a concept called variability. React knows what happened through the state changes in setState, so it renders. If the state is changed directly, React cannot sense it, so it cannot render. Simply put, it does not have two-way data binding like vue.

The constructor in a class component can be written or not. There are two main functions of writing this constructor:

  • In order to assign an object to this.state to initialize the value of the internal state
constructor(props){

    super(props)

    this.state = {n:12}

}



render(){

    return (

        <div>

                <h1>THE TIME IS {this.state.n}</h1>

        </div>

    )

}

 

Note that setState cannot be written here. The above method React can also be set outside, that is

 

state = {n:12}



render(){

    return (

        <div>

            <h1>THE TIME IS {this.state.n}</h1>

        </div>

    )

}
  • Bind instance to event handler function
constructor(props){

    super(props)

    this.addNum = function(){fn()}.bind(this)

}



render(){

    return (

        <button onClick={this.addNum}>+1</button>

    )

}

 

However, this method has also been replaced by a new method in React. The code is as follows:

addNum = ()=>{

    fn()

}



render(){

    return (

        <button onClick={this.addNum}>+1</button>

    )

}

 

Therefore, there is no need to write the above constructor method of inheriting the parent class.

function component

import {useState} from "react"

function FunctionComponent(){

    const [data,setData] = useState("你要传入的初始值")

    return (

        <div>SHOW DATA {state}</div>

    )

}

 

The function of setData here is similar to setState, but it can only be used to change the state of data. When it needs to be changed, a callback function is passed in. The function's argument is the previous value and returns a value to be changed. The essence of this method is to pass in a new object to change the value of the previous object in React. For this, you can easily write the changed value directly. By default, it will correspond to the current object and change its value. The
above method is much simpler than the original setState, but the trouble is that if there is multiple data, useState needs to be used multiple times and cannot Pass in multiple values ​​at once. However, in most cases, data management issues are managed by Redux, so React itself does not need to worry about it.

The pitfalls of setState

When changing the state of React components, a problem often encountered is the value merging of setState. Look at the following questions:

this.addNum = function () {

            this.setState({num:this.state.num+1})

            this.setState({num:this.state.num+1})

            this.setState({num:this.state.num+1})

        }.bind(this)

 

At this time, when the addNum function is triggered, num only adds 1. It didn't add 3 as we thought. React's own explanation for this is

Calling setState is actually asynchronous - don't expect this.state to be mapped to a new value immediately after calling setState.

The explanation for this is:

  1. No matter how many times setState is called, the update is not performed immediately. Instead, store the state to be updated in '_pendingStateQuene' and the component to be updated in 'dirtyComponent';
  2. When the root component didMount, the batch processing mechanism is updated to false. At this time, take out the state and components in '_pendingStateQuene' and 'dirtyComponent' for merge and update;

To put it simply, when React is executed, in order to improve performance, the setState to be updated is stored in an array. When React's own synchronization code is executed, before updating, the setState in the array is taken out and then rendered. In the above code, we added the synchronization code this.setState({num:this.state.num+1}) to setState, so when the batch is taken out, a merger will occur, and many setStates will be merged into one sentence. , thus only changing 1. Because of this mechanism, setState is made to look like asynchronous code, but in fact it is executed synchronously. At this time, if we change the previous synchronous code to asynchronous, we will get the results we want.

this.addNum = function () {

            setTimeout(()=>{ this.setState({num:this.state.num+1}) },0)

            setTimeout(()=>{ this.setState({num:this.state.num+1}) },0)

            setTimeout(()=>{ this.setState({num:this.state.num+1}) },0)

        }.bind(this)

At this time, the value is directly increased by 3, because the asynchronous code will be temporarily stored when the code is executed. Execute it after all synchronization codes have been executed. At this time, the batch processing mechanism has ended, so all three functions have been executed, so 3 is added. This is what I can think of so far. If there are new ones in the future, they will be added.

Guess you like

Origin blog.csdn.net/qq_17189095/article/details/131759715