Reactjs 当分数为0时,反应设置状态

Reactjs 当分数为0时,反应设置状态,reactjs,Reactjs,我正在做一个测验,现在我想根据用户的分数向他们显示不同的消息。此代码正在工作,但当分数为0时,未设置新状态 这似乎与prevProps有关。只有当您正确回答某个问题时,才会触发分数。是否有其他条件,我可以使用,也许 以下是当前状态下的所有代码: class App extends React.Component { constructor(props) { super(props); // Make it somewhat harder for che

我正在做一个测验,现在我想根据用户的分数向他们显示不同的消息。此代码正在工作,但当分数为0时,未设置新状态

这似乎与prevProps有关。只有当您正确回答某个问题时,才会触发分数。是否有其他条件,我可以使用,也许

以下是当前状态下的所有代码:

class App extends React.Component {

    constructor(props) {
        super(props);

        // Make it somewhat harder for cheaters to inspect the correct answer.
        document.getElementById('quiz').setAttribute('data-props', '');

        const data = JSON.parse(this.props.quiz);

        this.state = {
            data: data,
            nr: 0,
            total: data.length,
            showButton: false,
            questionAnswered: false,
            score: 0,
            popUpClass: 'popup-visible',
            quizVisible: false,
            id: data[0].id,
            question: data[0].question,
            answers: [
                data[0].answers[0], 
                data[0].answers[1], 
                data[0].answers[2], 
                data[0].answers[3]
            ],
            correct: data[0].correct
        }



        this.nextQuestion = this.nextQuestion.bind(this);
        this.handleShowButton = this.handleShowButton.bind(this);
        this.handleStartQuiz = this.handleStartQuiz.bind(this);
        this.handleIncreaseScore = this.handleIncreaseScore.bind(this);        
    }

    pushData(nr) {
        const data = this.state.data;
        this.setState({
            question: data[nr].question,
            answers: [data[nr].answers[0], data[nr].answers[1], data[nr].answers[2], data[nr].answers[3] ],
            correct: data[nr].correct,
            nr: this.state.nr + 1
        });
    }

    nextQuestion() {
        let { nr, total} = this.state;

        if(nr === total){
            this.setState({
                popUpClass: 'popup-visible',
                quizVisible: false
            });
        } else {
            this.pushData(nr);          
            this.setState({
                showButton: false,
                questionAnswered: false,
                quizVisible: true
            });
        }  
    }

    handleShowButton() {
        this.setState({
            showButton: true,
            questionAnswered: true
        });
    }

    handleStartQuiz() {
        this.setState({
            popUpClass: 'popup-hidden',
            quizVisible: true,
            nr: 1
        });
    }

    handleIncreaseScore() {
        this.setState({
            score: this.state.score + 1
        });
    }

    render() {
        let { nr, total, id, question, answers, correct, showButton, questionAnswered, popUpClass, quizVisible, score} = this.state;

        return (
            <div className="app-container">
                <Popup className={popUpClass} score={score} total={total} startQuiz={this.handleStartQuiz} key={nr} />           
                    {quizVisible ? 
                    (         
                        <div key={question} className="quiz"> 
                            <div className="quiz-box">
                            <span className="question-total">Fråga {nr} av {total}</span>
                            <h2 className="question">{question}</h2> 
                            <Answers 
                            key={id}
                            answers={answers} 
                            correct={correct} 
                            showButton={this.handleShowButton} 
                            isAnswered={questionAnswered} 
                            increaseScore={this.handleIncreaseScore} /> 
                            </div>
                            <div id="submit">
                               {showButton ? <button className="fancy-btn" onClick={this.nextQuestion} id={nr === total ? 'finishQuiz' : null}>{nr === total ? 'Slutför quiz' : 'Nästa fråga'}</button> : null}
                            </div>
                        </div>                     
                    ) : null}         

            </div>        
        );
    }
};

将上一个else if转换为else,因此条件测试如下所示:

如果得分>=高分=>…专家! 否则如果有一半的分数。。。小商品 否则如果0…需要练习 else=>做得不太好 这是逻辑的总括分支,用于不属于前面的测试用例之一的分数

组件更新


更新了上述链接的codesandbox。

如果达到了上一个条件,请在上一个条件内尝试console.log。可能this.props.score==0为假,因为this.props.score不是数字。如果它到达了那里,那么其他的东西就错了。为什么要这样做呢一次又一次的条件测试得分?没有最终的其他原因吗?@DrewReese如果我没有,那么我会得到这个未捕获的错误:超过了最大更新深度。当一个组件在componentWillUpdate或componentDidUpdate内部重复调用setState时,可能会发生这种情况。@如果您是对的,那么它不会到达它。您可以在一次检查道具时包装整个if-else if,然后在内部检查分数。简化了所有的条件测试。它是如此的复杂,因为它永远不会到达最后一个测试。不知何故,我从未达到第一个if分数!==除非我回答正确,否则我将使用prevProps.score。我更新了我的帖子,我认为你要求的是:几乎。需要查看更多计算分数和传递给组件的道具总数的内容。那个么分数真的只是全部正确答案吗?假设用户回答不正确,分数保持不变,但总数增加。或者总数是常量,分数是正确/尝试的百分比。现在用所有代码再次更新帖子:@Cami Updated answer,我想它会帮助你。
class Popup extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            title: 'Quiz',
            showStartButton: true
        };

        this.startQuizHandle = this.startQuizHandle.bind(this);
    }

    startQuizHandle() {                   
        this.props.startQuiz();
    }

    componentDidUpdate(prevProps) {

        let total = this.props.total;
        let highScore = total - 2;
        let halfScore = total / 2;

        if (this.props.score !== prevProps.score) {
            if (this.props.score >= highScore) {

                this.setState({
                    title: 'You are an expert!',
                })
            } else if (this.props.score >= halfScore && this.props.score <= highScore) {

                this.setState({
                    title: 'You are pretty good at this!'
                })
            }
            else if (this.props.score < halfScore && this.props.score > 0) {
                console.log('score less than half');
                this.setState({
                    title: 'You need some practice.'
                })
            }
            else {
                this.setState({
                    title: 'You did not do too well.',
                })
            }
        }
    }

    createMarkup(text) {
        return {__html: text};
    }   

    render() {

        let { title, intro, text, showStartButton } = this.state;
        let { className } = this.props;

        return (
            <div className={`popup-container ${ className }`}>
                <div className="popup">
                    <h1>{title}</h1>
                </div>
                {showStartButton ? <button className="fancy-btn" onClick={this.startQuizHandle}>Start Quiz</button> : null}

            </div>
        );
    }
}

export default Popup
class Answers extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            isAnswered: false,
            classNames: ['', '', ''],
            isDisabled: false
        }

        this.checkAnswer = this.checkAnswer.bind(this);
    }

    checkAnswer(e) {
        let { isAnswered } = this.props;  

        this.setState({
            isDisabled: true
        })

        if (!isAnswered) {
            let elem = e.currentTarget;
            let { correct, increaseScore } = this.props;
            let answer = Number(elem.dataset.id);
            let updatedClassNames = this.state.classNames;

            if (answer === correct) {
                updatedClassNames[answer - 1] = 'right';
                increaseScore();
            }
            else {

                updatedClassNames[answer - 1] = 'wrong';
            }

            this.setState({
                classNames: updatedClassNames
            })

            this.props.showButton();
        }
    }

    render() {
        let { answers } = this.props;
        let { classNames } = this.state;
        const { isDisabled } = this.state;

        return (
            <div id="answers">
                <ul>
                    <li onClick={this.checkAnswer} className={classNames[0]} data-id="1"><p className={isDisabled ? "disabled" : null}><span>A</span> {answers[0]}</p></li>
                    <li onClick={this.checkAnswer} className={classNames[1]} data-id="2"><p className={isDisabled ? "disabled" : null}><span>B</span> {answers[1]}</p></li>
                    <li onClick={this.checkAnswer} className={classNames[2]} data-id="3"><p className={isDisabled ? "disabled" : null}><span>C</span> {answers[2]}</p></li>
                </ul>
            </div>
        );
    }
}

export default Answers
componentDidUpdate(prevProps) {
  let total = this.props.total;
  let highScore = total - 2;
  let halfScore = total / 2;

  const { score } = this.props;

  if (score !== prevProps.score) {
    if (score >= highScore) {
      this.setState({
        title: "You are an expert!"
      });
    } else if (score >= halfScore && score <= highScore) {
      this.setState({
        title: "You are pretty good at this!"
      });
    } else if (score < halfScore && score > 0) {
      this.setState({
        title: "You need some practice."
      });
    } else {
      this.setState({
        title: "You did not do too well."
      });
    }
  }
}
checkScore = () => {
  const { score, total } = this.props;
  const highScore = total - 2;
  const halfScore = total / 2;

  if (score >= highScore) {
    this.setState({
      title: "You are an expert!"
    });
  } else if (score >= halfScore && score < highScore) {
    this.setState({
      title: "You are pretty good at this!"
    });
  } else if (score < halfScore && score > 0) {
    this.setState({
      title: "You need some practice."
    });
  } else {
    this.setState({
      title: "You did not do too well."
    });
  }
}

componentDidMount() {
  this.checkScore();
}

componentDidUpdate(prevProps) {
  const { score } = this.props;

  if (prevProps.score !== score) {
    this.checkScore();
  }
}