2016-12-08 60 views
2

我正在构建一个非常原始的测验应用程序与ReactJS,我无法更新我的Questions组件的状态。它的行为是它呈现questions阵列DOM的正确指标尽管this.state.questionNumber始终是落后一步在handleContinue()ReactJS onClick状态改变了一步

import React from "react" 

export default class Questions extends React.Component { 
    constructor() { 
    super() 
    this.state = { 
     questionNumber: 1 
    } 
    } 

    //when Continue button is clicked 
    handleContinue() { 
    if (this.state.questionNumber > 3) { 
     this.props.unMount() 
    } else { 
     this.setState({ 
     questionNumber: this.state.questionNumber + 1 
     }) 
     this.props.changeHeader("Question " + this.state.questionNumber) 
    } 
    } 

    render() { 
    const questions = ["blargh?", "blah blah blah?", "how many dogs?"] 
    return (
     <div class="container-fluid text-center"> 
     <h1>{questions[this.state.questionNumber - 1]}</h1> 
     <button type="button" class="btn btn-primary" onClick={this.handleContinue.bind(this)}>Continue</button> 
     </div> 
    ) 
    } 
} 
+1

我不确定我理解你的问题。我确实在排队更新它后立即访问'this.state.questionNumber'。 在React中设置状态是异步操作,因此不能保证它会及时更新下一个函数调用。 来自官方文档:_setState()不会立即改变this.state,但会创建一个挂起状态转换。在调用此方法后访问this.state可能会返回现有值。_ –

+0

在这种情况下,什么是一个好的选择? –

回答

10

setState()not necessarily a synchronous operation

setState()不会立即发生变异this.state而造成待处理的状态转换。访问this.state船尾

无法保证对setState的呼叫进行同步操作,并且可能会调用调用以提高性能。

为此,this.state.questionNumber仍可能在这里举行的前值:

this.props.changeHeader("Question " + this.state.questionNumber) 

相反,使用被调用一次状态转移的callback function完成

this.setState({ 
    questionNumber: this.state.questionNumber + 1 
},() => { 
    this.props.changeHeader("Question " + this.state.questionNumber) 
}) 
+1

我真的很喜欢这个回调函数解决方案 –

1

正如桑德维奇所说,如果你进入国家的右后方呃使用setState,你不能保证实际的价值。你可以这样做:

handleContinue() { 
    if (this.state.questionNumber > 3) { 
    this.props.unMount() 
    } else { 
    const newQuestionNumber = this.state.questionNumber + 1 
    this.setState({ 
     questionNumber: newQuestionNumber 
    }) 
    this.props.changeHeader("Question " + newQuestionNumber) 
    } 
}