javascript - 从子回调设置状态
问题描述
我创建了一个带有子组件的组件,该子组件使用在父组件中运行的事件。
当我查看状态更改时,它似乎成功了,但是在渲染时,该值是未定义的。
父组件:
constructor(props) {
super(props);
this.handleAnswer = this.handleAnswer.bind(this);
this.state = {
showQuestion: false,
showGetStarted: true,
correctAnswerTotal: 0,
question: <Question onAnswer={this.handleAnswer}/>,
emoji: <EmojiView correctQuestionCount="0"/>
};
}
handleAnswer(result) {
let emoji = this.state.emoji;
if (result === true) {
let newVal = this.state.correctTotal + 1;
alert('newVal: ' + newVal); // updates ------------------------
this.setState({ correctTotal: newVal }, () => {
let updatedVal = this.state.correctTotal;
alert('updatedVal: ' + updatedVal); // updates
});
} else {
this.setState({correctTotal : 0});
}
}
render() {
let correctTotal = this.state.correctQuestionCount;
alert('telling it to render with this count:' + correctTotal);
// correctTotal is undefined here -------------------
let emoji = <EmojiView correctQuestionCount={correctTotal}/>;
return (
<div className="App">
<header className="App-header">
<link href="https://fonts.googleapis.com/css2?family=Merriweather:wght@300;400&display=swap" rel="stylesheet"/>
</header>
<p>
{emoji}
</p>
</div>
);
}
子组件:
questionOneClicked = (user) => {
let lastQuestion = this.state.lastQuestion;
if (lastQuestion.correctIndex == 0) {
// TODO: they got it right!
var myQuestionModel = new QuestionModel("unused");
let randomQuestion = myQuestionModel.getRandomQuestion();
this.setState({lastQuestion: randomQuestion});
this.props.onAnswer(true);
} else {
this.props.onAnswer(false);
}
}
constructor(props, onAnswer) {
super(props);
//alert('props: ' + onAnswer);
var myQuestionModel = new QuestionModel("unused");
let randomQuestion = myQuestionModel.getRandomQuestion();
this.state = {
showQuestion: false,
showGetStarted: true,
lastQuestion: randomQuestion,
};
this.questionOneClicked = this.questionOneClicked.bind(this);
}
即使我的警报显示它已更新,为什么在父渲染()中未定义新状态?
解决方案
您正在更新状态 correctTotal 但您正在尝试访问未在任何地方设置的correctQuestionTotal
以下是您必须如何使用它
let correctTotal = this.state.correctTotal;
完整的渲染代码
render() {
let correctTotal = this.state.correctTotal;
alert('telling it to render with this count:' + correctTotal);
// correctTotal is undefined here -------------------
let emoji = <EmojiView correctQuestionCount={correctTotal}/>;
return (
<div className="App">
<header className="App-header">
<link href="https://fonts.googleapis.com/css2?family=Merriweather:wght@300;400&display=swap" rel="stylesheet"/>
</header>
<p>
{emoji}
</p>
</div>
);
附带说明一下,您不能将组件实例存储在 state 中,因为它们将无法像在 render 方法中那样进行 props 更改。如果您在状态中声明它们,它们将被视为仅在状态更改时更新的静态值,我猜您不会这样做
直接在渲染函数中渲染它们,比如
render() {
let correctTotal = this.state.correctTotal ;
alert('telling it to render with this count:' + correctTotal);
// correctTotal is undefined here -------------------
return (
<div className="App">
<header className="App-header">
<link href="https://fonts.googleapis.com/css2?family=Merriweather:wght@300;400&display=swap" rel="stylesheet"/>
</header>
<p>
<Question onAnswer={this.handleAnswer}/>
<EmojiView correctQuestionCount={correctTotal}/>
</p>
</div>
);
推荐阅读
- azure-data-factory-2 - 数据流接收到 csv 不使用文件名
- python - TypeError: 'int' 对象不可迭代 - 但它是一个列表
- jquery - 无法等待多个 AJAX 调用完成
- css - (sass):26096 如何修复 Rails 中的“Sass::SyntaxError: Invalid CSS after”错误
- javascript - 为三个 JS 导出时,Blender 模型和动画变形
- angular - 使用全局错误处理程序处理 NGXS(角度)中的错误
- javascript - 使用javascript将图像和文本从剪贴板复制到tinyMCE
- android - 如何在使用 javax.xml.soap 库时修复“NoClassDefFoundError: com.sun.xml.messaging.saaj.soap.SOAPDocumentImpl”错误
- mysql - 慢三重内连接
- java - JavaFX - BorderPane,确保右窗格始终获得最小宽度