Хуже того, что состояние изменилось другим состоянием. Это лучшее состояние, измененное реквизитом или обработчиком события.
Например, this.genNums()
не обязательно выполнять в componentDidMount()
this.setState(prevState => ({ result: prevState.num1 + prevState.num2 }));
код выше может быть изменен как:
this.setState({result: 2*this.genRandRange(1, 100)}) //assume this.genRandRange() return Number not String
И весь абзац может быть изменены:
import React, { Component } from "react";
export class MathQuiz extends Component {
constructor(props) {
super(props);
this.state = {
//num1: 0, if only used by other state
//num2: 0,
//op_type: "", if only used by other state
op: "",
result: 0,
no_right: 0,
no_wrong: 0,
options: <li />,
ans_pos: 0,
//options_and_pos: [[], 0] if only used by other state
};
}
componentDidMount() {
this.initQuiz(this.props.location.state.op_type);
}
initQuiz(op_type) {
if (op_type === "Addition") {
this.setState({
op:"+",
result: 2*this.genRandRange(1, 100)
});
/* Code */
}
else if (op_type === "Multiplication") {
this.setState({
op:"x",
result: Math.pow(this.genRandRange(1, 100),2),
options: this.getOptions(Math.pow(this.genRandRange(1, 100),2))[0].map((ele,
i) => (<li key={i}>{ele}</li>)),
ans_pos:this.getOptions(Math.pow(this.genRandRange(1, 100),2))[1]
});
}
}
genNums() {
this.setState({
num1: this.genRandRange(1, 100),
num2: this.genRandRange(1, 100)
});
}
getOptions(ans) {
/* Code */
return [ans_options, rand_pos];
}
render() {
return (
<div className="math_quiz_box">
/* JSX Code */
</div>
);
}
}
Приведенный выше код, просто сделайте setState один раз, может предотвратить проблему, такую как infinte l oop или цепочка обновления состояния.
Если вам нужно сделать цепочку setState, используйте
this.setState({
example:"example value"
},()=>{
// when example value has been set, then execute follow statement.
this.setState({
example2:this.state.example+"2" //example2:"example value2"
})
})