如何实现答题校验并根据布尔属性单独设置元素样式
问题修复与实现方案
我看了你的代码,发现几个关键问题导致需求无法正常实现,咱们一步步来修正:
核心问题梳理
- 状态管理不合理:你用单个
isCorrect状态跟踪所有句子的答案正确性,但每个句子都有独立的正确选项,单个状态根本没法区分不同句子的结果 - 事件绑定错误:
onChange事件绑定在<option>上是无效的,应该绑定在<select>标签上才能捕获用户的选择变化 - 渲染逻辑不匹配:当前的
isCorrectprops传递逻辑没法对应到每个句子的实际选择情况
完整修复代码
父组件代码
import { useState } from "react"; import { Wrapper, Sentence } from "./StyledComponents"; 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() { // 存储每个句子的用户选择,索引对应DATA的句子索引 const [userSelections, setUserSelections] = useState( Array(DATA.length).fill("") ); // 标记是否已经点击了检查按钮 const [isChecked, setIsChecked] = useState(false); // 处理下拉框选择变化,接收句子索引和选中的值 const handleValueChange = (index, selectedValue) => { const newSelections = [...userSelections]; newSelections[index] = selectedValue; setUserSelections(newSelections); }; // 获取某个句子的正确答案文本 const getCorrectAnswer = (answerOptions) => { return answerOptions.find(opt => opt.isCorrect).answerText; }; return ( <Wrapper> {DATA.map((sentence, index) => { const correctAnswer = getCorrectAnswer(sentence.answerOptions); // 判断当前句子的选择是否正确 const isAnswerCorrect = userSelections[index] === correctAnswer; return ( <Sentence key={index} isChecked={isChecked} isAnswerCorrect={isAnswerCorrect} > <span> {index + 1}. {sentence.sentenceFirstPart} </span> <select value={userSelections[index]} onChange={(e) => handleValueChange(index, e.target.value)} > {sentence.answerOptions.map((option, optIndex) => ( <option key={optIndex} value={option.answerText} > {option.answerText} </option> ))} </select> <span>{sentence.sentenceSecondPart}</span> </Sentence> ); })} <button onClick={() => setIsChecked(true)}>Check</button> </Wrapper> ); }
Styled Components代码
import styled from "styled-components"; export 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, isAnswerCorrect }) => { if (!isChecked) return ""; return isAnswerCorrect ? "green" : "red"; }}; } `;
代码说明
- 状态调整:用
userSelections数组存储每个句子的用户选择,索引和DATA的句子一一对应,精准跟踪每个句子的选择情况 - 事件绑定修正:把
onChange移到<select>上,通过e.target.value获取用户选择的值,同时传递句子索引来更新对应位置的选择 - 正确性判断:在渲染每个句子时,对比用户选择和该句子的正确答案,得到
isAnswerCorrect - 样式逻辑优化:只有当点击了检查按钮(
isChecked为true)时,才根据isAnswerCorrect设置边框颜色:正确显示绿色,错误/未选择显示红色
内容的提问来源于stack exchange,提问作者Adrian
相关产品推荐
相关产品推荐

