React中useState配合onClick时genreContainer变量不更新问题
React测验应用界面切换问题修复方案
问题根源
genreContainer是普通变量,不是React状态。React组件只有在状态更新或props变化时才会重新渲染,直接修改普通变量不会触发重渲染,所以点击Select按钮后界面不会切换到测验页。- 每次组件渲染时,
let genreContainer = false;都会重新执行,把变量重置为false,哪怕你在genreSelection里改成true,下一次渲染又变回初始值了。
修复步骤
1. 把genreContainer改成React状态
替换原来的普通变量声明,用useState管理:
// 替换 let genreContainer = false; const [genreContainer, setGenreContainer] = useState(false);
2. 修改genreSelection函数
不再直接赋值,改用状态更新函数触发组件重渲染:
const genreSelection = () => { setGenreContainer(true); // 通过setter更新状态 setCurrentGenre(selected - 1); setSelected(0); }
3. 修正状态初始化的类型问题
部分状态初始化用了0,但实际是布尔值场景,比如showResult应该初始化为false,避免类型混淆:
const [showResult, setShowResult] = useState(false);
4. 优化score更新逻辑(可选但推荐)
用函数式更新score,避免闭包陷阱,确保每次都基于最新状态值计算:
const updateScore = () => { if (selected === QuizData[0].data[currentGenre][currentQuestion].answer) { setScore(prevScore => prevScore + 1); } }
完整修复后的代码
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(false); const [currentGenre, setCurrentGenre] = useState(0); const [genreContainer, setGenreContainer] = useState(false); const changeQuestion = () => { updateScore(); if (currentQuestion < QuizData[0].data[currentGenre].length - 1) { setCurrentQuestion(currentQuestion + 1); setSelected(0); } else { setShowResult(true); } } const genreSelection = () => { setGenreContainer(true); setCurrentGenre(selected - 1); setSelected(0); } const updateScore = () => { if (selected === QuizData[0].data[currentGenre][currentQuestion].answer) { setScore(prevScore => prevScore + 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
内容的提问来源于stack exchange,提问作者Dipesh Ranjan
相关产品推荐
相关产品推荐

