如何让<select>标签受控并在点击按钮后重置其值?
实现受控
<select>并添加重置功能 要让<select>成为受控组件,核心是将它的选中值与状态变量绑定,同时在选项变化时更新该状态;重置功能则是将相关状态恢复到初始状态即可。以下是具体实现步骤:
1. 添加受控状态变量
新增selectedAnswers状态,用来记录每道题的选中选项值,初始值对应每个题目默认选中的空选项(即isCorrect: false的选项):
const [selectedAnswers, setSelectedAnswers] = useState( DATA.map(() => false) );
2. 改造选项切换事件
修改handleValueChange函数,让它更新selectedAnswers状态,同时我们可以直接通过这个状态判断答案是否正确,无需单独维护isCorrect状态:
const handleValueChange = (value, index) => { const newValue = value === "true"; setSelectedAnswers(prev => { const newAnswers = [...prev]; newAnswers[index] = newValue; return newAnswers; }); };
3. 将<select>设为受控组件
给<select>添加value属性,绑定到selectedAnswers[index],这样组件的选中值完全由状态驱动:
<select value={selectedAnswers[index]} onChange={(e) => handleValueChange(e.target.value, index)} >
4. 实现重置功能
给Reset按钮添加点击事件,把selectedAnswers重置为初始状态,同时关闭检查状态:
<button onClick={() => { setSelectedAnswers(DATA.map(() => false)); setIsChecked(false); }}>Reset</button>
完整修改后的代码
const DATA = [ { sentenceFirstPart: "It takes a lot of", sentenceSecondPart: "to learn how to waterski properly", answerOptions: [ { answerText: "", isCorrect: false }, { answerText: "attempt", isCorrect: false }, { answerText: "effort", isCorrect: true }, { answerText: "trial", isCorrect: false }, { answerText: "try", isCorrect: false } ] }, { sentenceFirstPart: "It was Thomas Edison who ", sentenceSecondPart: "electricity", answerOptions: [ { answerText: "", isCorrect: false }, { answerText: "detected", isCorrect: false }, { answerText: "invented", isCorrect: true }, { answerText: "found", isCorrect: false }, { answerText: "discovered", isCorrect: false } ] } ]; export default function App() { const [selectedAnswers, setSelectedAnswers] = useState( DATA.map(() => false) ); const [isChecked, setIsChecked] = useState(false); const handleValueChange = (value, index) => { const newValue = value === "true"; setSelectedAnswers(prev => { const newAnswers = [...prev]; newAnswers[index] = newValue; return newAnswers; }); }; return ( <Wrapper> {DATA.map((sentence, index) => ( <Sentence isChecked={isChecked} isCorrect={selectedAnswers[index]} key={index} > <span> {index + 1}. {sentence.sentenceFirstPart} </span> <select value={selectedAnswers[index]} onChange={(e) => handleValueChange(e.target.value, index)} > {sentence.answerOptions.map((option, optIndex) => ( <option value={option.isCorrect} key={optIndex}> {option.answerText} </option> ))} </select> <span>{sentence.sentenceSecondPart}</span> </Sentence> ))} <div> <button onClick={() => setIsChecked(true)}>Check</button> <button onClick={() => { setSelectedAnswers(DATA.map(() => false)); setIsChecked(false); }}>Reset</button> </div> </Wrapper> ); } const Wrapper = styled.div` display: flex; flex-direction: column; gap: 1rem; button { padding: 0rem 1rem; width: 6rem; } `; export const Sentence = styled.div` display: flex; align-items: center; span { font-size: 1.2rem; } select { margin: 0 0.5rem; border: 1px solid; padding: 0.2rem; border-radius: 4px; font-weight: 500; border-color: ${({ isChecked, isCorrect }) => !isChecked ? "currentColor" : isCorrect ? "green" : "red"}; } `;
关键说明
- 受控组件的核心是**
value绑定状态,onChange更新状态**,确保组件的选中值完全由状态控制,避免不受控组件的不可预测性。 - 重置操作本质就是将状态恢复到初始值,包括选中的选项和检查状态,这样
<select>会自动回到默认的空选项,边框样式也会恢复初始状态。
内容的提问来源于stack exchange,提问作者Adrian
相关产品推荐
相关产品推荐

