我正在尝试创建一个React应用,该应用在按下按钮a时添加一个react组件,然后重新渲染它。我使用状态内部的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>
);
}
}
答案 0 :(得分:5)
您正在做的几件事在反应上都是不好的做法。它们中的一个或多个可能导致您的问题。问题是:
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>
);
}
}
答案 1 :(得分:0)
this.list[3]= <p>Hola Mundo 4</p>;
上面的语句不会更改列表变量的引用。因此,设置状态在渲染时不会发生变化。而是做这样的事情-
this.setState({
list: this.list.concat(<p>Hola Mundo 4</p>)
});