React page does not refresh

Posted by JustinMs66 on Thu, 03 Mar 2022 17:38:18 +0100

Today, I write about the react project of the laboratory. One of the States is an array (be careful when you see that the state is an array. There are many pits!!!)

After operating on the array, the page does not refresh. After repeated tossing, it is reduced to the following code:

import React, { Component } from 'react'
import { Table, Tag, Space } from 'antd';
import "./App.css"
export default class App extends Component {
  state={
    a:[]
  }
  onclicka() {
    let tempa=this.state.a;
    tempa.push({
      "name":"a",
      "age":20
    });
    this.setState({
      a:tempa,
    });
  }
  render() {
    const dataSource = this.state.a.map((item,index)=>{
      return{
        key:index,
        name:item.name,
        age:item.age
      }
    })
    const columns = [
      {
        title: 'full name',
        dataIndex: 'name',
      },
      {
        title: 'Age',
        dataIndex: 'age',
      }
    ];
    return (
      <div>
      <button onClick={this.onclicka.bind(this)}>a</button><br></br>
      <Table bordered dataSource={this.state.a} columns={columns} />;       
      </div>
    )
  }
}

Click the button to start the onclick event and obtain the status this state. A, assign to tempa, then add an object in tempa, then call setstate, set a to tempa, then the following table calls this.. state. A) the logic is smooth and seems to have no problem. However, after clicking, you will find that the page does not respond.

Why? Why? Why?

In the final analysis, it is still an array. If you replace this array with number, there will be no problem. It seems that this state. A is assigned to tempa. From then on, tempa and this state. A it doesn't matter anymore, but is it really so?

No, c language also has this problem. tempa is a reference, and it still points to this state. A's memory, so tempa push es, which is this state. This is modified directly in a state. After a , setstate is called, which seems to be updated, but tempa and this state. A address points to a place. dataSource={this.state.a} finds this state. There is no change on the surface of a, so the virtual dom of react will not change, so the view will not be updated (but the render function will still be called, and this.state.a will also change).

In essence, it is also a deep copy and a shallow copy of an object

Modify to refresh the page:

import React, { Component } from 'react'
import { Table, Tag, Space } from 'antd';
import "./App.css"
export default class App extends Component {
  state={
    a:[]
  }
  onclicka() {
    let tempa=this.state.a;
    tempa.push({
      "name":"a",
      "age":20
    });
    this.setState({
      a:tempa,
    });
  }
  render() {
    const dataSource = this.state.a.map((item,index)=>{
      return{
        key:index,
        name:item.name,
        age:item.age
      }
    })
    const columns = [
      {
        title: 'full name',
        dataIndex: 'name',
      },
      {
        title: 'Age',
        dataIndex: 'age',
      }
    ];
    return (
      <div>
      <button onClick={this.onclicka.bind(this)}>a</button><br></br>
      <Table bordered dataSource={dataSource} columns={columns} />;       
      </div>
    )
  }
}

Where has it been revised?  

Last sentence:

<Table bordered dataSource={dataSource} columns={columns} />; 

dataSource={dataSource}, I will look for datasource as the display content. How does datasource come from? Is to traverse this state. A later, react can't see this state. Changes in a, but you can see through traversal. The datasource passes through this state. After traversal of a, it changes, so react adopts a new data source, and the page is refreshed.

However, this can only be used as a way to make up for the lost sheep. The most fundamental way is to avoid directly modifying the state, especially the state of array type

Do not use push, pop, shift, unshift, splice and other methods to modify the state of array types, because these methods are modified on the basis of the original array, while concat, slice and filter will return a new array.

This is the most critical sentence. Do not use the method of modifying the original array, but use the method of returning a new array.

The extension operator can also serve as a method to return a new array.

Refer to this article for details:

https://www.jianshu.com/p/15c033b341a8 Knowledge points that react must know to change state - brief book

Therefore, the standard writing of this code is as follows:

import React, { Component } from 'react'
import { Table, Tag, Space } from 'antd';
import "./App.css"
export default class App extends Component {
  state={
    a:[]
  }
  onclicka() {
    let tempa=[...this.state.a,{
      "name":"a",
      "age":20
    }]
    this.setState({a:tempa});
  }
  render() {
    const dataSource = this.state.a.map((item,index)=>{
      return{
        key:index,
        name:item.name,
        age:item.age
      }
    })
    const columns = [
      {
        title: 'full name',
        dataIndex: 'name',
      },
      {
        title: 'Age',
        dataIndex: 'age',
      }
    ];
    return (
      <div>
      <button onClick={this.onclicka.bind(this)}>a</button><br></br>
      <Table bordered dataSource={dataSource} columns={columns} />;       
      </div>
    )
  }
}

Using the extension operator and returning a new array can cause the page to be updated.

At this point, < table bordered datasource = {datasource} columns = {columns} / >;  

Or < table bordered datasource = {this. State. A} columns = {columns} / >;

The effect is the same.

The big pit of react should be kept in mind in the future!!! (not only arrays, but also objects)

Several related articles:

https://www.jb51.net/article/216192.htm

https://blog.csdn.net/qq_40041944/article/details/108199039

https://www.cnblogs.com/ww01/p/13231462.html

https://www.jianshu.com/p/15c033b341a8

https://blog.csdn.net/weixin_39939012/article/details/80876022

 

Topics: Javascript Front-end React