ReactJS onClick 状态改变落后一步

ReactJS onClick state change one step behind

我正在使用 ReactJS 构建一个非常原始的测验应用程序,但我在更新 Questions 组件的状态时遇到了问题。它的行为是将 questions 数组的正确索引呈现给 DOM,尽管 this.state.questionNumber 总是比 handleContinue() 落后一步:

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>
    )
  }
}

setState()not necessarily a synchronous operation:

setState() does not immediately mutate this.state but creates a pending state transition. Accessing this.state aft

There is no guarantee of synchronous operation of calls to setState and calls may be batched for performance gains.

因此,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)
})

正如 Sandwichz 所说,如果您在使用 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)
  }
}