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

React答题网站按钮ID重复问题:如何为每个按钮分配唯一ID

为React答题网站的每个选项按钮分配唯一ID的解决方案

你的问题核心是:给每道题传了同一个ID,导致该题下所有按钮点击后返回的ID都一样,根本没给单个按钮分配独立标识。下面是具体的修复方案:

步骤1:重构选项数据,给每个选项生成唯一ID

首先在App组件里,把每道题的正确答案和错误答案合并成一个数组,同时用nanoid给每个选项生成唯一ID,还能顺便打乱选项顺序(符合答题网站的常规需求)。

步骤2:修改QuestionPage组件,渲染带唯一ID的选项按钮

让QuestionPage接收处理后的选项列表,每个按钮点击时传递对应选项的ID和内容,而非整道题的ID。

步骤3:更新状态管理,跟踪用户选择

在App组件里维护状态,记录用户每道题选择的选项ID,方便后续验证答案。


修改后的App组件代码

import QuestionPage from "./components/Question_page";
import React from "react";
import { nanoid } from 'nanoid'
import { BrowserRouter as Router, Route, Routes } from "react-router-dom"
import JsonData from "./JsonData";

export default function App() {
    // 维护用户选择:key是题目索引,value是选中的选项ID
    const [userAnswers, setUserAnswers] = React.useState({});

    // 处理题目数据:合并选项+生成唯一ID+打乱顺序
    const processedQuestions = JsonData[0].results.map((question, questionIndex) => {
        // 合并正确和错误选项,给每个选项加唯一ID和是否正确的标记
        const allOptions = [
            ...question.incorrect_answers,
            question.correct_answer
        ].map(option => ({
            id: nanoid(),
            text: option,
            isCorrect: option === question.correct_answer
        }));

        // 打乱选项顺序(可选,答题网站常用)
        const shuffledOptions = allOptions.sort(() => Math.random() - 0.5);

        return {
            ...question,
            options: shuffledOptions,
            questionIndex
        };
    });

    // 处理选项点击:记录用户选择的题目索引和选项ID
    function handleOptionSelect(questionIndex, optionId) {
        setUserAnswers(prev => ({
            ...prev,
            [questionIndex]: optionId
        }));
        console.log(`题目${questionIndex+1},选中选项ID:${optionId}`);
    }

    // 验证答案逻辑
    function checkAnswers() {
        let score = 0;
        processedQuestions.forEach((question, index) => {
            const selectedOption = question.options.find(opt => opt.id === userAnswers[index]);
            if (selectedOption?.isCorrect) {
                score++;
            }
        });
        alert(`你的得分是:${score}/${processedQuestions.length}`);
    }

    return (
        <Router>
            <NavBar/>
            <Routes>
                <Route path="/" element={<Start/>}/>
                <Route path="/question" element={
                    <div>
                        {processedQuestions.map((question) => (
                            <QuestionPage
                                key={question.questionIndex}
                                question={question.question}
                                options={question.options}
                                selectedOptionId={userAnswers[question.questionIndex]}
                                onOptionSelect={(optionId) => handleOptionSelect(question.questionIndex, optionId)}
                            />
                        ))}
                        <div className="check-answer-container">
                            <button className="check-answer" onClick={checkAnswers}>Check answer</button>
                        </div>
                        <hr/>
                    </div>
                }/>
            </Routes>
        </Router>
    );
}

修改后的QuestionPage组件代码

import React from "react";

export default function Question_page(props) {
    // 根据是否选中设置按钮样式
    const getButtonStyle = (optionId) => ({
        backgroundColor: props.selectedOptionId === optionId ? "#59E391" : "grey",
        margin: "5px",
        padding: "8px 16px",
        border: "none",
        borderRadius: "4px",
        cursor: "pointer"
    });

    return (
        <div className="main-question-container">
            <div className="question">
                <h3>{props.question}</h3>
            </div>
            <div className="question-button">
                {props.options.map(option => (
                    <button
                        key={option.id}
                        style={getButtonStyle(option.id)}
                        onClick={() => props.onOptionSelect(option.id)}
                    >
                        {option.text}
                    </button>
                ))}
            </div>
        </div>
    );
}

关键改动说明

  • 每个选项都有了独立的nanoid生成ID,点击按钮时传递的是选项自身的ID,不再是整道题的ID
  • 合并并打乱选项顺序,更贴近真实答题场景
  • 用userAnswers状态跟踪用户每道题的选择,便于后续验证答案和更新按钮样式
  • QuestionPage组件根据选中状态动态切换按钮背景色,无需依赖原有的isHeld属性

内容的提问来源于stack exchange,提问作者Tombrown Anuma

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 03:05:29