首页 > 解决方案 > setState 不重新渲染数组内的反应组件

问题描述

我正在尝试创建一个反应应用程序,该应用程序在按下按钮时添加反应组件,然后重新呈现它。我正在使用 state 内的 p 元素数组作为测试。事件处理函数使用 setState 来修改数组,但由于某种原因它不会重新渲染组件,因此更改(新元素)不会显示在屏幕上。我做错了什么?

import React, {Component} from "react";

export default class Agenda extends React.Component{

  constructor(props){

    super(props);

    this.list = [];

    this.state = {

      list:[]

    };

    this.addItem = this.addItem.bind(this);

    const items = ["Hola Mundo 1","Hola Mundo 2","Hola Mundo 3"];

    const itemComponent = items.map((item) => 
      <p>{item}</p>
    );

    this.list = itemComponent;
    this.state.list = itemComponent; 

  }

  addItem(){

    //Adds a new paragraph element at the end of the array
    this.list[3]= <p>Hola Mundo 4</p>;

    this.setState(

      {
        list: this.list
      }
    );

  }

  render(){


    return(

      <div id={this.props.id} className={this.props.className}> 


        {this.state.list}

        <button onClick={this.addItem}>

          Add item

        </button>

      </div>

    );

  }
}

标签: javascriptreactjsweb

解决方案


您正在做的几件事在反应中是不好的做法。其中一个或多个可能会导致您的问题。问题是:

1)不要将组件保存在状态中。您的状态应该只是确定组件的最小数据,并且组件本身会显示在渲染中。通过将组件存储在状态中,您很容易忘记更新状态,从而导致渲染不改变。

2)不要将状态复制为实例变量。通过这样做,您只是强迫自己手动保持两条数据彼此同步。取而代之的是,拥有单一的事实来源,并从中获得其他一切。

3)不要改变状态。如果要将项目添加到数组中,请创建一个新数组,它是旧数组的浅表副本,然后附加到该新数组。React 依赖于不可变的状态来判断状态是否已更改,因此突变是一种简单的方法,可以意外地使重新渲染不会发生。

export default class Agenda extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      list: ['Hola Mundo 1', 'Hola Mundo 2', 'Hola Mundo 3'],
    };

    this.addItem = this.addItem.bind(this);
  }

  addItem() {
    this.setState((oldState) => {
      const newList = [...oldState.list];
      newList.push('Hola Mundo 4');
      return { list: newList };
    });
  }

  render() {
    return (
      <div id={this.props.id} className={this.props.className}>
        {this.state.list.map(item =>
          <p>{item}</p>
        )}
        <button onClick={this.addItem}>
            Add item
        </button>
      </div>
    );
  }
}

推荐阅读