状态数组在设置状态时被替换为 1
Array in state being replaced with a 1 when setting state
我是 React 的新手,所以如果我试图做一些无法完成的事情,我提前道歉。我正在尝试在该州的 "scores" 数组中存储一个对象,其中包含一个 id 和一个选择分数。我在一个名为 handleScore 的函数中构建对象,当我第一次单击选择并随后立即将分数数组记录到控制台时,状态似乎正确显示,但是当我在渲染中将分数数组记录到控制台时方法,我只得到 1。当我进行选择然后再次单击按钮时,我也会得到 1。有谁知道发生了什么事?这是代码:
handleScore = (id, score, idx) => {
const { statements, scores } = this.state;
let scoreObj = {};
Object.assign(scoreObj, {'id': id, 'score': score});
if (statements[0][idx].isSelected) {
this.setState({
scores: scores[0].push(scoreObj)
});
console.log("scores array: ", scores[0]); //outputs an array containing [{id: "O1", score: "4"}]
} else {
console.log("scores array: ", scores[0]); // outputs 1
}
}
在 render() 方法中:
render() {
console.log("this.state.scores from render method: ", this.state.scores); // outputs 1 instead of [{id: "O1", score: "4"}]
return (
<div>
<div className="statements-wrapper">
{
this.state.statements[0].map((item, index) => (
<div
key={item.id} onClick={(e) => {
e.preventDefault();
this.handleScore(item.id, match.params.score, index)
}}>
<a href="#">{item.statement}</a>
</div>
)
)
}
</div>
</div>
)
预期输出:
scores: [
[{id: "O1", score: 4}, {id: "G1", score: 3}, {id: "B1", score: 2}, {id: "R1", score: 1}],
[{id: "O2", score: 4}, {id: "G2", score: 3}, {id: "B2", score: 2}, {id: "R2", score: 1}],
[{id: "O3", score: 4}, {id: "G3", score: 3}, {id: "B3", score: 2}, {id: "R3", score: 1}],
[{id: "O4", score: 4}, {id: "G4", score: 3}, {id: "B4", score: 2}, {id: "R4", score: 1}],
[{id: "O5", score: 4}, {id: "G5", score: 3}, {id: "B5", score: 2}, {id: "R5", score: 1}]
]
我认为问题源于在使用 setState
时将整个 this.state.scores
替换为单个数组。要保留其余元素数组,您需要执行以下操作:
handleScore = (id, score, idx) => {
const { statements, scores } = this.state;
if (statements[0][idx].isSelected) {
// this assumes you want to append the first array (hence 'index === 0') in this.state.scores
this.setState({
scores: scores.map((item, index) => index === 0 ? [...item, {'id': id, 'score': score}] : item)
});
}
}
同样重要的是要注意上面的方法以及 push
会将新对象放在数组的 end 并且 setState
是异步的,因此之后立即进行控制台日志记录 scores
可能不可靠。
要删除内部数组之一中的特定对象,您可以使用 filter:
// replacing an inner object by id value
scores.map((item, index) => index === 0 ?
item.filter((i) => i.id !== "01")
: item
)
我是 React 的新手,所以如果我试图做一些无法完成的事情,我提前道歉。我正在尝试在该州的 "scores" 数组中存储一个对象,其中包含一个 id 和一个选择分数。我在一个名为 handleScore 的函数中构建对象,当我第一次单击选择并随后立即将分数数组记录到控制台时,状态似乎正确显示,但是当我在渲染中将分数数组记录到控制台时方法,我只得到 1。当我进行选择然后再次单击按钮时,我也会得到 1。有谁知道发生了什么事?这是代码:
handleScore = (id, score, idx) => {
const { statements, scores } = this.state;
let scoreObj = {};
Object.assign(scoreObj, {'id': id, 'score': score});
if (statements[0][idx].isSelected) {
this.setState({
scores: scores[0].push(scoreObj)
});
console.log("scores array: ", scores[0]); //outputs an array containing [{id: "O1", score: "4"}]
} else {
console.log("scores array: ", scores[0]); // outputs 1
}
}
在 render() 方法中:
render() {
console.log("this.state.scores from render method: ", this.state.scores); // outputs 1 instead of [{id: "O1", score: "4"}]
return (
<div>
<div className="statements-wrapper">
{
this.state.statements[0].map((item, index) => (
<div
key={item.id} onClick={(e) => {
e.preventDefault();
this.handleScore(item.id, match.params.score, index)
}}>
<a href="#">{item.statement}</a>
</div>
)
)
}
</div>
</div>
)
预期输出:
scores: [
[{id: "O1", score: 4}, {id: "G1", score: 3}, {id: "B1", score: 2}, {id: "R1", score: 1}],
[{id: "O2", score: 4}, {id: "G2", score: 3}, {id: "B2", score: 2}, {id: "R2", score: 1}],
[{id: "O3", score: 4}, {id: "G3", score: 3}, {id: "B3", score: 2}, {id: "R3", score: 1}],
[{id: "O4", score: 4}, {id: "G4", score: 3}, {id: "B4", score: 2}, {id: "R4", score: 1}],
[{id: "O5", score: 4}, {id: "G5", score: 3}, {id: "B5", score: 2}, {id: "R5", score: 1}]
]
我认为问题源于在使用 setState
时将整个 this.state.scores
替换为单个数组。要保留其余元素数组,您需要执行以下操作:
handleScore = (id, score, idx) => {
const { statements, scores } = this.state;
if (statements[0][idx].isSelected) {
// this assumes you want to append the first array (hence 'index === 0') in this.state.scores
this.setState({
scores: scores.map((item, index) => index === 0 ? [...item, {'id': id, 'score': score}] : item)
});
}
}
同样重要的是要注意上面的方法以及 push
会将新对象放在数组的 end 并且 setState
是异步的,因此之后立即进行控制台日志记录 scores
可能不可靠。
要删除内部数组之一中的特定对象,您可以使用 filter:
// replacing an inner object by id value
scores.map((item, index) => index === 0 ?
item.filter((i) => i.id !== "01")
: item
)