useState Hook 在 React JS 中使用 onClick 按钮实现时,变量的值不会改变。

huangapple go评论58阅读模式
英文:

value of variable not changing using useState Hook in React JS when implemented using onClick button

问题

在这里,genreContainer变量的值在调用genreSelection函数时没有改变。

const genreSelection = () => {
    genreContainer = true; // 这里改变了genreContainer的值,但问题在于它没有触发组件重新渲染
    setCurrentGenre(selected - 1); // 这里改变了currentGenre的值
    setSelected(0);
}

问题在于genreContainer是一个普通的JavaScript变量,它的改变并不会触发React组件重新渲染。要在React组件中实现状态的改变并触发重新渲染,你应该使用useState来管理它。这样,当你调用setState函数时,它会触发组件重新渲染。

你可以将genreContainer改成一个useState,像这样:

const [genreContainer, setGenreContainer] = useState(false);

const genreSelection = () => {
    setGenreContainer(true); // 使用setGenreContainer来改变genreContainer的值
    setCurrentGenre(selected - 1);
    setSelected(0);
}

这样做之后,genreContainer的值改变时会触发组件重新渲染,你应该能够看到预期的结果。

英文:

I implemented a nested ternary operator to render one of 3 things based on condition, it is for the quiz app, one renders the results, on the quiz and one has the option to choose the genre of the quiz.

I defaulted it in such a way that the genre selection defaults, and when the selection is made, clicking the button calls a function that sets the genre's value and changes the variable which essentially changes the ternary operator to change the rendering component.

The problem is genreContainer variable isn't changing from false to true, which is implemented in the function.

import { React, useState } from 'react'
import './quiz.css'
import { QuizData } from '../../data/QuizData'
import Result from '../result/Result'



const Quiz = () => {
    const [currentQuestion, setCurrentQuestion] = useState(0);
    const [score, setScore] = useState(0);
    const [selected, setSelected] = useState(0);
    const [showResult, setShowResult] = useState(0);
    const [currentGenre, setCurrentGenre] = useState(0);
    let genreContainer = false;

    const changeQuestion = () => {
        updateScore();
        if (currentQuestion < QuizData[0].data[currentGenre].length - 1) {
            setCurrentQuestion(currentQuestion + 1);
            setSelected(0);
        }
        else {
            setShowResult(true);
        }

    }

    const genreSelection = () => {
        genreContainer = true;
        setCurrentGenre(selected - 1);
        setSelected(0);

    }

    const updateScore = () => {
        if (selected === QuizData[0].data[currentGenre][currentQuestion].answer) {
            setScore(score + 1)
        }
    }

    return (
        <div className='container'>
            {showResult ? (
                <Result score={score} totalScore={QuizData[0].data[currentGenre].length} />
            ) : (
                <>
                    {genreContainer ? (
                        <>
                            <div className="question">
                                <span id='question-number'>
                                    {currentQuestion + 1}.
                                </span>
                                <span id='question-txt'>
                                    {QuizData[0].data[currentGenre][currentQuestion].question}
                                </span>
                            </div>
                            <div className="option-container">
                                {QuizData[0].data[currentGenre][currentQuestion].options.map((option, i) => {
                                    return (
                                        <button className={`option-btn ${selected === i + 1 ? 'checked' : null}`}
                                            key={i}
                                            onClick={() => setSelected(i + 1)}
                                        >
                                            {option}
                                        </button>
                                    )
                                })}
                            </div>
                            <input type="button" value="Next" id='next-button' onClick={changeQuestion} />
                        </>
                    ) : (
                        <>
                            <div className="question">
                                <span id='question-txt'>
                                    Choose your genre of Quiz
                                </span>
                            </div>
                            <div className="option-container">
                                {QuizData[0].options.map((option, i) => {
                                    return (
                                        <button className={`option-btn ${selected === i + 1 ? 'checked' : null}`}
                                            key={i}
                                            onClick={() => {
                                                setSelected(i + 1);
                                            }}
                                        >
                                            {option}
                                        </button>
                                    )
                                })}
                            </div>
                            <input type="button" value="Select" id='next-button' onClick={genreSelection} />
                            
                        </>
                    )}
                    
                </>
            )}
        </div>
    )
}
export default Quiz

here the genreContainer variable's value isn't changing when genreSelection function is called.

答案1

得分: 0

问题是genreContainer变量没有从false变为true。

是的。但是,然后你立刻更新了状态。更新状态会触发重新渲染。当组件重新渲染时,它会做什么?

let genreContainer = false;

如果你想要一个值在重新渲染时保持不变,有一种机制可以做到...状态。例如:

const [genreContainer, setGenreContainer] = useState(false);

以及:

const genreSelection = () => {
    setGenreContainer(true);
    setCurrentGenre(selected - 1);
    setSelected(0);
}
英文:

> The problem is genreContainer variable isn't changing from false to true

Yes it is. But, then you immediately update state. Updating state triggers a re-render. And what does the component do when it renders? This:

let genreContainer = false;

If you want a value to persist across renders, there's a mechanism for that... state. For example:

const [genreContainer, setGenreContainer] = useState(false);

And:

const genreSelection = () => {
    setGenreContainer(true);
    setCurrentGenre(selected - 1);
    setSelected(0);
}

huangapple
  • 本文由 发表于 2023年6月22日 04:52:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/76527059.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定