如何使用 componentDidMount 重置状态?
How to reset state with componentDidMount?
我是 React 的新手,我正在做一个测验。我现在想做的是在您遇到新问题时将类名重置为初始状态。我想我想使用 componentDidUpdate 但不确定它是如何工作的。
componentDidUpdate() {
this.setState({
classNames: ["", "", "", ""]
});
}
这里是完整的组件代码:
class Answers extends React.Component {
constructor(props) {
super(props);
this.state = {
isAnswered: false,
classNames: ["", "", "", ""]
};
this.checkAnswer = this.checkAnswer.bind(this);
}
checkAnswer(e) {
let { isAnswered } = this.props;
if (!isAnswered) {
let elem = e.currentTarget;
let { correct, increaseScore } = this.props;
let answer = Number(elem.dataset.id);
let updatedClassNames = this.state.classNames;
if (answer === correct) {
updatedClassNames[answer - 1] = "right";
increaseScore();
} else {
updatedClassNames[answer - 1] = "wrong";
}
this.setState({
classNames: updatedClassNames
});
this.props.showButton();
}
}
componentDidUpdate() {
this.setState({
classNames: ["", "", "", ""]
});
}
render() {
let { answers } = this.props;
let { classNames } = this.state;
return (
<div id="answers">
<ul>
<li onClick={this.checkAnswer} className={classNames[0]} data-id="1">
<p>{answers[0]}</p>
</li>
<li onClick={this.checkAnswer} className={classNames[1]} data-id="2">
<p>{answers[1]}</p>
</li>
<li onClick={this.checkAnswer} className={classNames[2]} data-id="3">
<p>{answers[2]}</p>
</li>
<li onClick={this.checkAnswer} className={classNames[3]} data-id="4">
<p>{answers[3]}</p>
</li>
</ul>
</div>
);
}
}
export default Answers;
感谢任何帮助!自从我学习以来,对整个代码项目的反馈也非常感谢。
下面是一个link完整的项目:
问题是,如果您在 componentDidUpdate
中更改状态,它将立即触发另一次更新,因此会再次 运行 componentDidUpdate
并导致无限循环。所以你应该把 setState
移到别处,或者把它放在一个条件后面。例如:
componentDidUpdate() {
if (!this.state.classNames.every(className => className === "") { // Check if there is an item in the array which doesn't match an empty string ("")
this.setState({ // Only update state if it's necessary
classNames: ["", "", "", ""]
});
}
}
您可以找到更新的 CodeSandbox here
首先,您必须添加一个按钮来重置 类 名称,此按钮将调用一个函数来重置它们,例如:
import React from "react";
class Answers extends React.Component {
constructor(props) {
super(props);
this.state = {
isAnswered: false,
classNames: ["", "", "", ""]
};
}
checkAnswer = e => {
let { isAnswered } = this.props;
if (!isAnswered) {
let elem = e.currentTarget;
let { correct, increaseScore } = this.props;
let answer = Number(elem.dataset.id);
let updatedClassNames = this.state.classNames;
if (answer === correct) {
updatedClassNames[answer - 1] = "right";
increaseScore();
} else {
updatedClassNames[answer - 1] = "wrong";
}
this.setState({
classNames: updatedClassNames
});
this.props.showButton();
}
};
reset = () => {
this.setState({
isAnswered: false,
classNames: ["", "", "", ""]
});
};
render() {
let { answers } = this.props;
let { classNames } = this.state;
return (
<div id="answers">
<button onClick={this.reset}>RESET</button>
<ul>
<li onClick={this.checkAnswer} className={classNames[0]} data-id="1">
<p>{answers[0]}</p>
</li>
<li onClick={this.checkAnswer} className={classNames[1]} data-id="2">
<p>{answers[1]}</p>
</li>
<li onClick={this.checkAnswer} className={classNames[2]} data-id="3">
<p>{answers[2]}</p>
</li>
<li onClick={this.checkAnswer} className={classNames[3]} data-id="4">
<p>{answers[3]}</p>
</li>
</ul>
</div>
);
}
}
export default Answers;
如果您更改 key
的答案,有一个简单的解决方法(并推荐作为 React 最佳实践),工作演示:https://codesandbox.io/s/another-quiz-wgycs
<Answers
key={question} // <-- oh hi
answers={answers}
correct={correct}
...
理想情况下,您会使用 id
,并且由于大多数现代数据结构都有一个 ID,因此使用 key={question_id}
是理想的选择,因为密钥必须是唯一的:
{
id: 1
question: 'What does CSS stand for?',
answers: [...],
correct: 3
},
{
id: 2,
....
}
如果没有,您将不得不使用 prevProps
:
componentDidUpdate(prevProps) {
if (this.props.question !== prevProps.question) {
this.setState(....)
}
}
我真的推荐key
方式,因为这会强制创建一个新的组件,在实践中如果你需要不断检查变化的道具,它会变得有点难以跟踪。
记住,理想情况下应该有一个 id
,因为如果问题文本相同,则会导致难以找到的严重错误。
此外,与其保存类名,不如将 selected
保存为索引并在渲染方法中选择正确的类名。
componentDidUpdate()
在更新发生后立即被调用。初始渲染不会调用此方法。
我最近遇到过这种情况。您必须在 componentDidUpdate() {}
中使用相同的代码。这是我所做的。
componentDidUpdate(prevProps) {
if (this.props.questions !== prevProps.questions) {
const shuffledAnswerOptions = this.props.questions.map(question =>
question.answer_options &&
this.shuffleArray(question.answer_options)
);
this.setState({
current_question:this.props.questions &&
this.props.questions[0],
question_image_url: this.props.questions &&
this.props.questions[0] &&
this.props.questions[0].question_image_url,
answerOptions: shuffledAnswerOptions[0],
numberOfQuestions: this.props.questions &&
this.props.questions.length
});
}
}
在您的情况下,您还 prevSate
参数。
这是一个示例实现:
componentDidUpdate(prevProps, prevState) {
if(this.state.assignment !== prevState.assignment){
document.getElementById(prevState.assignment.id) && document.getElementById(prevState.assignment.id).classList.remove("headactiveperf");
}
if(this.state.assessment !== prevState.assessment){
document.getElementById(prevState.assessment.id) && document.getElementById(prevState.assessment.id).classList.remove("headactiveperf");
}
if(this.state.study_group_id !== prevState.study_group_id){
document.getElementById(prevState.study_group_id) && document.getElementById(prevState.study_group_id).classList.remove("klassactiveperf");
}
}
我是 React 的新手,我正在做一个测验。我现在想做的是在您遇到新问题时将类名重置为初始状态。我想我想使用 componentDidUpdate 但不确定它是如何工作的。
componentDidUpdate() {
this.setState({
classNames: ["", "", "", ""]
});
}
这里是完整的组件代码:
class Answers extends React.Component {
constructor(props) {
super(props);
this.state = {
isAnswered: false,
classNames: ["", "", "", ""]
};
this.checkAnswer = this.checkAnswer.bind(this);
}
checkAnswer(e) {
let { isAnswered } = this.props;
if (!isAnswered) {
let elem = e.currentTarget;
let { correct, increaseScore } = this.props;
let answer = Number(elem.dataset.id);
let updatedClassNames = this.state.classNames;
if (answer === correct) {
updatedClassNames[answer - 1] = "right";
increaseScore();
} else {
updatedClassNames[answer - 1] = "wrong";
}
this.setState({
classNames: updatedClassNames
});
this.props.showButton();
}
}
componentDidUpdate() {
this.setState({
classNames: ["", "", "", ""]
});
}
render() {
let { answers } = this.props;
let { classNames } = this.state;
return (
<div id="answers">
<ul>
<li onClick={this.checkAnswer} className={classNames[0]} data-id="1">
<p>{answers[0]}</p>
</li>
<li onClick={this.checkAnswer} className={classNames[1]} data-id="2">
<p>{answers[1]}</p>
</li>
<li onClick={this.checkAnswer} className={classNames[2]} data-id="3">
<p>{answers[2]}</p>
</li>
<li onClick={this.checkAnswer} className={classNames[3]} data-id="4">
<p>{answers[3]}</p>
</li>
</ul>
</div>
);
}
}
export default Answers;
感谢任何帮助!自从我学习以来,对整个代码项目的反馈也非常感谢。
下面是一个link完整的项目:
问题是,如果您在 componentDidUpdate
中更改状态,它将立即触发另一次更新,因此会再次 运行 componentDidUpdate
并导致无限循环。所以你应该把 setState
移到别处,或者把它放在一个条件后面。例如:
componentDidUpdate() {
if (!this.state.classNames.every(className => className === "") { // Check if there is an item in the array which doesn't match an empty string ("")
this.setState({ // Only update state if it's necessary
classNames: ["", "", "", ""]
});
}
}
您可以找到更新的 CodeSandbox here
首先,您必须添加一个按钮来重置 类 名称,此按钮将调用一个函数来重置它们,例如:
import React from "react";
class Answers extends React.Component {
constructor(props) {
super(props);
this.state = {
isAnswered: false,
classNames: ["", "", "", ""]
};
}
checkAnswer = e => {
let { isAnswered } = this.props;
if (!isAnswered) {
let elem = e.currentTarget;
let { correct, increaseScore } = this.props;
let answer = Number(elem.dataset.id);
let updatedClassNames = this.state.classNames;
if (answer === correct) {
updatedClassNames[answer - 1] = "right";
increaseScore();
} else {
updatedClassNames[answer - 1] = "wrong";
}
this.setState({
classNames: updatedClassNames
});
this.props.showButton();
}
};
reset = () => {
this.setState({
isAnswered: false,
classNames: ["", "", "", ""]
});
};
render() {
let { answers } = this.props;
let { classNames } = this.state;
return (
<div id="answers">
<button onClick={this.reset}>RESET</button>
<ul>
<li onClick={this.checkAnswer} className={classNames[0]} data-id="1">
<p>{answers[0]}</p>
</li>
<li onClick={this.checkAnswer} className={classNames[1]} data-id="2">
<p>{answers[1]}</p>
</li>
<li onClick={this.checkAnswer} className={classNames[2]} data-id="3">
<p>{answers[2]}</p>
</li>
<li onClick={this.checkAnswer} className={classNames[3]} data-id="4">
<p>{answers[3]}</p>
</li>
</ul>
</div>
);
}
}
export default Answers;
如果您更改 key
的答案,有一个简单的解决方法(并推荐作为 React 最佳实践),工作演示:https://codesandbox.io/s/another-quiz-wgycs
<Answers
key={question} // <-- oh hi
answers={answers}
correct={correct}
...
理想情况下,您会使用 id
,并且由于大多数现代数据结构都有一个 ID,因此使用 key={question_id}
是理想的选择,因为密钥必须是唯一的:
{
id: 1
question: 'What does CSS stand for?',
answers: [...],
correct: 3
},
{
id: 2,
....
}
如果没有,您将不得不使用 prevProps
:
componentDidUpdate(prevProps) {
if (this.props.question !== prevProps.question) {
this.setState(....)
}
}
我真的推荐key
方式,因为这会强制创建一个新的组件,在实践中如果你需要不断检查变化的道具,它会变得有点难以跟踪。
记住,理想情况下应该有一个 id
,因为如果问题文本相同,则会导致难以找到的严重错误。
此外,与其保存类名,不如将 selected
保存为索引并在渲染方法中选择正确的类名。
componentDidUpdate()
在更新发生后立即被调用。初始渲染不会调用此方法。
我最近遇到过这种情况。您必须在 componentDidUpdate() {}
中使用相同的代码。这是我所做的。
componentDidUpdate(prevProps) {
if (this.props.questions !== prevProps.questions) {
const shuffledAnswerOptions = this.props.questions.map(question =>
question.answer_options &&
this.shuffleArray(question.answer_options)
);
this.setState({
current_question:this.props.questions &&
this.props.questions[0],
question_image_url: this.props.questions &&
this.props.questions[0] &&
this.props.questions[0].question_image_url,
answerOptions: shuffledAnswerOptions[0],
numberOfQuestions: this.props.questions &&
this.props.questions.length
});
}
}
在您的情况下,您还 prevSate
参数。
这是一个示例实现:
componentDidUpdate(prevProps, prevState) {
if(this.state.assignment !== prevState.assignment){
document.getElementById(prevState.assignment.id) && document.getElementById(prevState.assignment.id).classList.remove("headactiveperf");
}
if(this.state.assessment !== prevState.assessment){
document.getElementById(prevState.assessment.id) && document.getElementById(prevState.assessment.id).classList.remove("headactiveperf");
}
if(this.state.study_group_id !== prevState.study_group_id){
document.getElementById(prevState.study_group_id) && document.getElementById(prevState.study_group_id).classList.remove("klassactiveperf");
}
}