首页 > 解决方案 > 从子回调设置状态

问题描述

我创建了一个带有子组件的组件,该子组件使用在父组件中运行的事件。

当我查看状态更改时,它似乎成功了,但是在渲染时,该值是未定义的。

父组件:

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

即使我的警报显示它已更新,为什么在父渲染()中未定义新状态?

标签: javascriptreactjs

解决方案


您正在更新状态 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>
      );

推荐阅读