React单选组件问题:点击检查按钮后状态丢失及背景色设置需求
单选按钮选中状态丢失问题修复
问题
点击主APP里的「检查答案」按钮后,单选按钮会自动取消选中,selectedAnswer状态变成undefined,没法正常给错误选项标红。
原因分析
handleOptionChange逻辑冗余:单选按钮只有在选中时才会触发onChange,原代码里判断event.target.checked再设置值,反而可能在意外场景下把状态设为null,导致选中状态丢失。- 高亮逻辑不完整:正确选项的高亮没关联正确答案,错误选项的判断逻辑也没和正确答案绑定,同时父组件触发检查后可能导致子组件状态重置。
修复方案
1. 修正单选按钮的 onChange 逻辑
直接移除多余的checked判断,选中时直接把值存入状态:
const handleOptionChange = (event) => { setSelectedAnswer(event.target.value); };
2. 统一背景色判断逻辑
提取一个函数来处理所有选项的背景色,区分正确选项(绿色)和选中的错误选项(红色):
const getLabelBgColor = (choice) => { if (!props.isSelected) return ''; // 正确选项显示绿色 if (choice === props.correctAnswer) return 'lightgreen'; // 选中的错误选项显示红色 if (choice === selectedAnswer) return 'red'; return ''; };
注:需要确保父组件传递了correctAnswer属性,用来标识正确选项
3. 避免子组件状态意外重置
检查父组件的「检查答案」按钮逻辑,如果点击时导致SecondPage组件重新挂载(比如key变化、条件渲染导致卸载后再挂载),就把selectedAnswer状态移到父组件里,通过props传给子组件,这样状态就不会丢失了。
修复后的完整代码
export default function SecondPage(props){ const [selectedAnswer, setSelectedAnswer] = React.useState(); const handleOptionChange = (event) => { setSelectedAnswer(event.target.value); }; const getLabelBgColor = (choice) => { if (!props.isSelected) return ''; if (choice === props.correctAnswer) return 'lightgreen'; if (choice === selectedAnswer) return 'red'; return ''; }; return( <div className="radio-toolbar"> <legend className="quiz">{he.decode(props.question)}</legend> <label style={{backgroundColor: getLabelBgColor(props.choiceOne)}}> <input type="radio" name={props.id} value={props.choiceOne} checked={selectedAnswer === props.choiceOne} onChange={handleOptionChange} /> {props.choiceOne} </label> <label style={{backgroundColor: getLabelBgColor(props.choiceTwo)}}> <input type="radio" name={props.id} value={props.choiceTwo} checked={selectedAnswer === props.choiceTwo} onChange={handleOptionChange} /> {props.choiceTwo} </label> <label style={{backgroundColor: getLabelBgColor(props.choiceThree)}}> <input type="radio" name={props.id} value={props.choiceThree} checked={selectedAnswer === props.choiceThree} onChange={handleOptionChange} /> {props.choiceThree} </label> <label style={{backgroundColor: getLabelBgColor(props.choiceFour)}}> <input type="radio" name={props.id} value={props.choiceFour} checked={selectedAnswer === props.choiceFour} onChange={handleOptionChange} /> {props.choiceFour} </label> </div> ) }
内容的提问来源于stack exchange,提问作者Saad Farrag
相关产品推荐
相关产品推荐

