我有一个按钮,可以将内容添加到几个数组中。当使用.push时,元素正确添加(因为看起来像使用了for循环),但是当我第二次单击按钮时,出现上述错误。这是我的一些代码:
class App extends Component {
constructor(props) {
super(props);
this.state = {
key: uuid(),
title: "",
author: "",
questions: [],
answers: []
};
this.handleChange = this.handleChange.bind(this);
}
//yada yada
addQuestion = () => {
questionNum++;
this.setState({
questions: this.state.questions.concat(["question", "hi"])
});
console.log(this.state.questions);
for (var i = 0; i < 4; i++) {
this.setState({
answers: this.state.answers.push({
answerChoice: "",
key: uuid()
})
});
}
console.log(this.state.answers);
console.log(questionNum);
console.log(this.state.title);
console.log(this.state.author);
};
render() {
//yada yada
<div>
<form>
<div className="Intro">
Give your Quiz a title:{" "}
<input
type="text"
value={this.state.title}
onChange={this.handleChange}
name="title"
/>
<br />
Who's the Author?{" "}
<input
type="text"
value={this.state.author}
onChange={this.handleChange}
name="author"
/>
<br />
<br />
</div>
<div className="questions">
Now let's add some questions... <br />
{this.addQuestion}
</div>
</form>
<button onClick={this.addQuestion}>Add Question</button>
</div>;
//yada yada
}
}
export default App;
但是当我更换
this.setState({
answers: this.state.answers.push({
answerChoice: '',
key: uuid()
})
})
与
this.setState({
answers: this.state.answers.concat({
answerChoice: '',
key: uuid()
})
})
似乎我的for循环不起作用(因为未添加其中四项)。我对React和JS还是很陌生,所以任何技巧都会有所帮助。
谢谢!
答案 0 :(得分:4)
您不应使用push
,因为它会改变当前处于您的状态的阵列。
当更新从当前状态中派生的状态时,最好给setState
一个函数并从中返回状态更改。否则,存在覆盖状态更新的风险,第二个示例就是这种情况。
您可以改为散布状态中的当前数组,然后向其中添加新对象。
this.setState(previousState => {
return {
answers: [...previousState.answers, { answerChoice: '', key: uuid() }]
};
});
如果您愿意,也可以将状态更新分组在一起,并且仅使用setState
一次:
addQuestion = () => {
questionNum++;
this.setState(previousState => {
const questions = [...previousState.questions, "question", "hi"];
const answers = [...previousState.answers];
for (var i = 0; i < 4; i++) {
answers.push({
answerChoice: "",
key: uuid()
});
}
return { questions, answers };
});
});