2016-12-08 62 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) 
    } 
}