setState()

  1. Data in React state cannot be changed directly

    The code in the example is to directly change (wrong)

    1
    2
    3
    4
    changeWeather(){
    const isHot=this.state.isHot
    this.state.Hot=!isHot //Error!
    console.log(this.state.isHot)}

    The immediate consequence of the change is that the console.log output can toggle between true and false, but the page is not re-rendered. Here you can check the status from inspect => Components, and find that isHot in the status is always the initial value.


  2. setState()

    The state state cannot be changed directly, it needs to be changed with the help of a built-in API: setState(). setState() is an asynchronous update.

    setState() is available in the React.Components prototype through the inheritance chain. An object is to be written in setState(), which is the same as state.

    1
    2
    3
    4
    changeWeather(){
    const isHot=this.state.isHot
    this.setState({isHot : ! isHot})
    }

    At this time, the state in inspect=>Components will switch.


  3. The state update action of setState() is merged rather than replaced

    When the state is updated, the object in setState() will not replace the object in the state as a whole, but only modify the part with the same name.


  4. Times of code executions in class components

    The constructor constructor(props) is only executed once, the time ReactDOM.render is called when the instance is created.

    render is called 1+n times. 1 is the time it was initialized, and n is the number of state updates.

    changeWeather(): It is called several times when the click event is triggered several times. setState is in changeWeather() .

    Therefore, React will re-call render once whenever the state is modified via setState. Components are also known as state machines.


  5. Shorthand for state and function

    The this in constructor(props) and render() in the class component points to the class component instance. Because the this in the constructor itself is the instance object of the class, and the this of render() is also the instance object because react creates an instance of the class when ReactDOM.render(<component tag/>...) is executed. And it is called by instance.render().

    There is a problem with the this pointer in the custom function, because the custom function is not called through instance.custom function, but called through event callbacks (custom functions are almost all called through event callbacks).


    Code before simplification

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    class Weather extends React.Component{
    constructor(props){
    super(props)
    this.state = {isHot:false,wind:'breeze'}
    this.changeWeather = this.changeWeather.bind(this) //***
    }
    render(){
    const {isHot,wind} = this.state
    return <h1>onClick={this.changeWeather}Today's weather {isHost?'hot':'cool'},{wind}</h1>
    }
    changeWeather(){
    const isHot = this.state.isHot
    this.setState({isHot:!isHot})
    }
    }

    Simplified way

    1. Assignment statements can be written directly in the class, such as a=1, instead of this.property name=fixed value written in the constructor.

      This code is to add an attribute to the instance object of the class. If the initial value of this property is passed in from outside, it must be written in the constructor. Therefore, state initialization can be written outside the constructor.

      1
      state = {isHot: false, wind: "breeze"}

    2. this.changeWeather = this.changeWeather.bind (this) This statement can be omitted.

      The purpose of this statement is to change the point of this and copy the changeWeather method on the class prototype object to the instance attribute changeWeather. After being omitted, the changeWeather method does not exist on the function prototype object, but only the instance attribute has changeWeather. And the value of this property is an anonymous function.


      Note that it is an error to omit the method changeWeather=function(){}. This is because it just changed the changeWeather to another place, and it still reports an error after clicking (because there is no .bind(this) to change the direction). So the correct way is arrow functions.


      The arrow function does not have its own this. When using this in the arrow function, it will find the this of the outer function of the arrow function to use. Therefore, this in the arrow function is the instance object of the component.

      1
      2
      3
      4
      changeWeather = () => {
      const isHot = this.state.isHot
      this.setState({isHot:!isHot})
      }

      When writing a custom method in a class component in the future, it must be written in the form of an assignment statement + an arrow function. It is impossible not to write an assignment statement, and a syntax error will be reported. Because if you don’t write assignment, you are putting the function on the class prototype. There is no syntax that can put the arrow function on the class prototype.

      1
      changeWeather() => {} //Wrong way of writing

    abbreviated code

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    class Weather extends React.Component{
    state = {isHot:false,wind:'breeze'}

    changeWeather = () => {
    const isHot = this.state.isHot
    this.setState({isHot:!isHot})
    }

    render(){
    const {isHot,wind} = this.state
    return <h1>onClick={this.changeWeather}Today's weather {isHost?'hot':'cool'},{wind}</h1>
    }
    }

Share