反应讨厌的错误,我不知道

时间:2019-01-04 14:54:45

标签: javascript reactjs

我对React非常陌生,试图开发一个带有问题的测验,我有一个Quiz组件,该组件接收带有问题的Json的数组。这是测验类:

class Quiz extends Component {

  constructor(props){
    super(props);
    this.state={
      questions: this.props.jsonArray,
      score: 0,
      currentQuest: 0,
      guessedAnswer:'',
    };
    this.handleSubmit = this.handleSubmit.bind(this);
    this.handleChange= this.handleChange.bind(this);
  }

  handleSubmit(event){
    console.log("In parent submited");
    let correct_answer= this.state.questions[this.state.currentQuest].correct_answer;
    console.log("Correct answer is " + correct_answer);
    if(this.state.guessedAnswer===correct_answer){
      console.log('Correct answer');
      this.setState({score : this.state.score + 1});
    }
    console.log('Your score is ' + this.state.score);
    this.setState({currentQuest : this.state.currentQuest + 1});
    console.log("Current question is " + this.state.currentQuest);

  }

  handleChange(val){

    this.setState({guessedAnswer: val});
  }

  render(){
    return(
      <div>
        {this.state.currentQuest< this.state.questions.length ? <QuestComp question={this.state.questions[this.state.currentQuest]} onChangeValue={this.handleChange} onFormSubmit={this.handleSubmit}/> :null}
      </div>
    );

  }

}

它使用参数调用Question组件,当前问题,这是Question组件:

class QuestComp extends Component{


  constructor(props){
    super(props);
    this.state={
      question: this.props.question,
      rerender: false
    }
    console.log('In constructor in question');
  }

  updateAnswer=(e)=>{
    console.log('changed ' + e.target.value);
    this.props.onChangeValue(e.target.value);
  }
  submitForm=(e)=>{
    e.preventDefault();
    this.setState({question : this.props.question});
    this.props.onFormSubmit(e);
  }


  render(){
    console.log("Rerender child" + this.props.question.question);
    let incorrect_answers=[];
    for(let i=0;i<this.state.question.incorrect_answers.length;i++){
      incorrect_answers.push(this.state.question.incorrect_answers[i]);
    }
    let randNum=Math.round(Math.random()* (incorrect_answers.length-1));
    let correct_answer=this.state.question.correct_answer;
    incorrect_answers.splice(randNum,0,correct_answer);
    return(

      <form onSubmit={this.submitForm}>

        <h2><p>{this.state.question.category}:</p></h2>
        <h3><p>The question is {this.state.question.question}</p></h3>

          {incorrect_answers.map((answer,i) => <div key={i}><input name="somename" onChange={this.updateAnswer} type="radio" key={i} value={answer} />{answer} </div>)}
          <input type="submit" className="btn btn-success" value="Submit"/>
        </form>
    );
  }
}

这个想法很简单,每次用户提交表单时,我都会增加currentQuestion状态并将下一个问题传递给QuestComp以显示它,问题是我第一次必须实际单击两次提交按钮才能转到下一个问题,它只是不呈现它,当我将console.log放入QuestComp呈现方法中以查看它收到了什么问题时,实际上这是正确的问题,它只是不显示它,我不知道为什么,所以第一次按2次“提交”按钮转到下一个问题,在此之后一切正常,一次按下并呈现下一个问题,为什么?

2 个答案:

答案 0 :(得分:1)

主要问题与QuestComp中的问题状态有关,与Quiz传递的问题道具不同步。

只需直接使用从Quiz传递来的道具,而不是将道具设置为QuizComp中的状态。将道具设置成这样的状态是一种反模式且容易出错。

要解决此问题,只需将this.state.question中的所有QuestComp替换为this.props.question

答案 1 :(得分:0)

setState是异步的,需要一些时间才能完成。您的this.props.onFormSubmit(e);会立即触发,而不必等待它结束。

尝试以这种方式使用它:

this.setState({question : this.props.question},
() => this.props.onFormSubmit(e);
);

它应在setState结束后触发,并使您的内容正常工作。

当您第一次单击提交时,您将this.setState({ question: this.props.question });运行this.state.questions[this.state.currentQuest]

currentQuest的当前值为0,因此它再次显示您对index = 0的疑问。 handleSubmit立即将其增加到1,所以每次下一次都很好。

您需要先增加该数字。