我正在尝试在任务列表上分别为每个人添加一个新任务。我成功获取了每个人的ID,并在addItem函数中向该人信息数组添加了新任务,当我登录控制台时,我什至可以看到我的新状态被更新为正确的值。但是,我收到此错误->无法读取未定义的属性“地图”。另外,在这种情况下更新状态的最佳方法是什么?我知道散布运算符或Object.assign被大量使用,但是当存在嵌套的状态级别时,我应该怎么想?
class App extends React.Component {
state = {
data: [
{
id: 0,
title: "Winnie",
info: [
"Buy eggs from the grocery store",
"Return text books to the campus",
"Buy eggs from the grocery store",
"Return text books to the campus"
]
},
{
id: 1,
title: "Maggie",
info: [
"Finish cleaning before 11 pm",
"See if Michael has any recommendations",
"Buy eggs from the grocery store",
"Return text books to the campus"
]
}
};
addItem = id => {
const enteredTask = prompt("Please enter a task");
this.state.data.map(d => {
if (d.id == id) {
d.info = [...d.info, enteredTask];
console.log("d info", d);
this.setState({
data: [...this.state.data, d.info]
});
console.log("state is", this.state.data);
}
});
};
render() {
return (
<div>
<h3 className="header">Dashboard</h3>
<div className="card-parent">
{this.state.data.map(d => {
return <Card key={d.id} info={d} addItem={this.addItem} />;
})}
</div>
</div>
);
}
}
class Card extends React.Component {
render() {
return (
<div className="card-style">
<h4 className="card-header">{this.props.info.title}</h4>
{this.props.info.info.map(i => {
return <p className="card-info">{i}</p>;
})}
<button
onClick={() => this.props.addItem(this.props.info.id)}
className="card-button"
>
Add New Task
</button>
</div>
);
}
}
答案 0 :(得分:1)
此错误可能来自:渲染函数内部的this.props.info.info.map
。我认为您原打算改为this.props.info.map
。
理想情况下,您可以执行this.props.info && this.props.info.map
。
只需确定代码中包含的数组,然后再映射它,就首先要检查它是否存在。在映射代码中的任何数组之前执行此操作
// for any array named arr
arr && arr.map(//your operation)
即使arr = []
也没有元素,也就是将其类型转换为布尔值时仍然为真。
关于第二部分,传播运算符或 Object.assign 的思想是更改引用,从而对更新状态做出反应。
但是请注意,这两种方法仅在向下一级更改。因此,对于嵌套对象或更具体而言,您可以执行以下操作:
addItem = id => {
const enteredTask = prompt("Please enter a task");
const newData = [...this.state.data]; // changed array's reference here
// changed reference of nested object
newData[id].info = [...d.info, enteredTask];
this.setState({ data: newData });
};
希望这会有所帮助:)
答案 1 :(得分:0)
您需要先检查this.state.data
,然后才能在map
方法中使用render
来停止出现的错误:
render() {
return (
<div>
<h3 className="header">Dashboard</h3>
<div className="card-parent">
{this.state.data && this.state.data.map(d => {
return <Card key={d.id} info={d} addItem={this.addItem} />;
})}
</div>
</div>
);
}
...以及render
组件的Card
方法中的相同内容:
{this.props.info.info && this.props.info.info.map(i => {
return <p className="card-info">{i}</p>;
})}
然后,您可以在更新数据之后而不是在addItem
的每次迭代中更新setState
方法以调用map
:
addItem = id => {
const enteredTask = prompt("Please enter a task");
const newData = this.state.data.map(d => {
if (d.id == id) {
d.info = [...d.info, enteredTask];
}
return d;
});
this.setState({ data: newData });
};
我希望这会有所帮助。
答案 2 :(得分:0)
这是根据尼克的建议而稍作更改的答案,谢谢大家的帮助
addItem = id => {
const enteredTask = prompt("Please enter a task");
let new_arr = [...this.state.data];
this.state.data.map(d => {
if (d.id === id) {
new_arr[id].info = [...d.info, enteredTask];
this.setState({
data: new_arr
});
}
});
};