You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React函数组件中实现.map()渲染的单个答题选项点击后样式独立切换的方案

解决React Quiz选项点击仅改变单个组件样式的问题

嘿,我看你现在的问题是点击某个答题选项时,所有选项的样式都跟着变了对吧?这是因为你用了一个全局的correct布尔状态——只要这个状态变成true,所有通过map渲染的AnswerOption组件都会触发correct类的样式,自然做不到只改变点击的那个选项。咱们调整一下状态管理的逻辑就能搞定:

核心思路

把单一的布尔状态改成记录用户选中的具体选项,然后让每个AnswerOption组件自己判断:我是不是被选中的那个?我是不是正确答案?以此来决定应用什么样式。

修改后的完整代码

主组件部分

import { useState, Fragment } from 'react';
import Question from './Question';
import AnswerOption from './AnswerOption';

const Quiz = () => {
  // 替换原来的correct状态,用selectedAnswer存储用户点击的选项内容
  const [selectedAnswer, setSelectedAnswer] = useState(null);
  const DUMMY_QUESTIONS = [
    {
      id: 1,
      question: 'What is the Big O of merge sort?',
      options: [
        { number: 1, answer: 'O(1)'},
        { number: 2, answer: 'O(log n)' },
        { number: 3, answer: 'O(n)' },
        { number: 4, answer: 'O(n log n)' }
      ],
      answer: 'O(n log n)'
    }
  ];

  // 处理选项点击,存储用户选中的选项
  const handleOptionClick = (selected) => {
    setSelectedAnswer(selected);
  };

  return (
    <Fragment>
      <div>
        <Question question={DUMMY_QUESTIONS[0].question} />
      </div>
      <div>
        {DUMMY_QUESTIONS[0].options.map(option =>
          <AnswerOption
            key={option.number}
            id={option.number}
            option={option.answer}
            // 告诉组件:我是不是被选中的?我是不是正确答案?
            isSelected={selectedAnswer === option.answer}
            isCorrect={option.answer === DUMMY_QUESTIONS[0].answer}
            click={() => handleOptionClick(option.answer)}
          />
        )}
      </div>
    </Fragment>
  );
};

export default Quiz;

AnswerOption组件部分

const AnswerOption = props => {
  // 根据选中状态和是否正确拼接类名
  let optionClass = 'answer-option';
  if (props.isSelected) {
    optionClass += props.isCorrect ? ' answer-option--correct' : ' answer-option--incorrect';
  }

  return (
    <div className={optionClass} onClick={() => props.click(props.option)}>
      <p>{props.option}</p>
    </div>
  );
};

export default AnswerOption;

为什么这样有效?

  1. 状态精准控制:selectedAnswer只会存储用户点击的那一个选项内容,不会影响其他选项
  2. 组件独立判断:每个AnswerOption只关心自己是否是被选中的那个,以及自己是否是正确答案,完全独立于其他选项的状态
  3. 样式逻辑清晰:通过拼接类名的方式,只有被选中的选项才会根据对错应用绿色/红色背景

可选优化(按需添加)

如果想让用户选中后不能再点击其他选项,可以给AnswerOption的点击事件加个判断:

// 在AnswerOption组件里修改onClick
onClick={() => !props.isSelected && props.click(props.option)}

内容的提问来源于stack exchange,提问作者eric L

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 05:22:45