Javascript 当我的3个状态在React-onClick函数中按预期更新时,其中一个状态落后了

Javascript 当我的3个状态在React-onClick函数中按预期更新时,其中一个状态落后了,javascript,reactjs,react-hooks,Javascript,Reactjs,React Hooks,我有一个组件,可以在react中创建多项选择题。单击以选择答案时, 此组件增加给出的正确或错误答案的数量,并计算总体正确率百分比。onClick函数是: const handleAnswer = (e) => { let correctItalianValue = correctAnswerContainer.current.innerText; if (e.target.innerText === correctEnglishValue(correctIt

我有一个组件,可以在react中创建多项选择题。单击以选择答案时, 此组件增加给出的正确或错误答案的数量,并计算总体正确率百分比。onClick函数是:

const handleAnswer = (e) => {
        let correctItalianValue = correctAnswerContainer.current.innerText;
        if (e.target.innerText === correctEnglishValue(correctItalianValue)) {
            inCorrect()
        } else {
            inWrong()
        }
    }
如果答案正确,我正在运行下面的函数,如果不是另一个函数:

    const inCorrect = () => {
        setCorrectAnswer(correctAnswer => correctAnswer + 1)
        setAnswerSum(answerSum => answerSum + 1)
        setAverageSuccess(val => percentage(answerSum, correctAnswer, wrongAnswer))
        setAnswer(answer => !answer)
    }

    const inWrong = () => {
        setWrongAnswer(wrongAnswer => wrongAnswer + 1)
        setAnswerSum(answerSum => answerSum + 1)
        setAverageSuccess(val => percentage(answerSum, correctAnswer, wrongAnswer))
        setAnswer(answer => !answer)
    }
    const percentage = (total, correct, wrong) => {
        if (correct === 0) {
            return 0
        } else if (wrong === 0) {
            return 100
        } else {
            return Math.round(100 * correct / total)
        }
    }
然后,我将这些状态作为道具传递给另一个组件,如下所示:

<AnswerCounter correctAnswer={correctAnswer} wrongAnswer={wrongAnswer}
                answerSum={answerSum} averageSuccess={averageSuccess} />

在该组件中,我将呈现正确和错误问题的数量以及回答的问题总数

const AnswerCounter = ({ correctAnswer, wrongAnswer, answerSum, averageSuccess }) => {
    return (
        <section className="mt-5">
            <div className="d-flex justify-content-between mb-3">
                <h5>Correct: {correctAnswer}</h5>
                <h5>Wrong: {wrongAnswer}</h5>
                <h5>Total : {answerSum}</h5>
            </div>
            <div className="progress">
                <div className="progress-bar progress-bar-striped bg-dark" role="progressbar"
                    style={{ width: `${averageSuccess}%` }} aria-valuenow={averageSuccess}
                    aria-valuemin="0" aria-valuemax="100">{averageSuccess} %
                </div>
            </div>
        </section>
    )
}

export default AnswerCounter

const AnswerCounter=({correctAnswer,errowAnswer,answerSum,averageSuccess})=>{
返回(
正确:{correctAnswer}
错误:{错误答案}
总计:{answerSum}
{averageSuccess}%
)
}
导出默认应答计数器

当这些数据(correctAnswer、ErrorAnswer、correctAnswer)正确呈现时,帮助我显示进度条的averageSuccess道具总是落后于一个步骤,有时落后于多个步骤。我知道更新状态是异步的,需要先传递前一个状态,然后再更新状态,但正如您所看到的那样,这并没有起作用。我也尝试了useEffect,但也不起作用。当I console.log averageSuccess用户通过单击其中一个回答按钮回答问题时,有时我会将averageSuccess值视为0(初始值),即使已单击两次或三次按钮并调用handleAnswer函数。我希望有人能帮助我。谢谢。

这是因为正如Brian所说,我使用过时的值来计算平均值(在setAverageSuccess中),将其移动到useEffect hook解决了我的问题。

你有一个过时的闭包。您正在使用回调设置平均状态,但仍然使用过时的值。您需要为平均计算再次增加它们,或者将平均更新移动到
useffect
。非常感谢Brian,将setAverageSuccess移动到useffect解决了我的问题。