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

React组件仅最后一题渲染input type="radio"问题求助

React组件单选框渲染异常:仅最后一题显示radio控件

我开发了一个React组件,用户点击按钮后从API获取3道题目,每道题包含4个可选答案。但组件渲染后,仅最后一题显示input type="radio"控件。

问题截图

组件代码

import React, { Component } from 'react';
import { Form, Button } from 'react-bootstrap';
import { Configuration, OpenAIApi } from 'openai';

class QuizApp extends Component {
  constructor() {
    super();
    this.state = {
      book: '',
      questions: [],
      message: '',
    };

    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
    this.handleAnswer = this.handleAnswer.bind(this);
  }

  handleChange(event) {
    this.setState({ book: event.target.value });
  }

  async handleSubmit(event) {
    event.preventDefault();

    const configuration = new Configuration({
      apiKey: 'APIKEY',
    });
    const openai = new OpenAIApi(configuration);

    try {
      const response = await openai.createCompletion({
        model: 'text-davinci-003',
        prompt: `Generate 3 quiz questions about the book "${this.state.book}" with 4 possible answers for each question"`,
        temperature: 1,
        max_tokens: 200,
        top_p: 1,
        frequency_penalty: 0,
        presence_penalty: 0,
      });

      const questions = [];
      let match;
      const regex = /([^]*)\n([^]*)\n([^]*)\n([^]*)\n([^]*)\n([^]*)/g;

while ((match = regex.exec(response.data.choices[0].text))) {
  const question = {
    question: match[1],
    correctAnswer: match[2],
    wrongAnswer1: match[3],
    wrongAnswer2: match[4],
    wrongAnswer3: match[5],
  };
  questions.push(question);
}

this.setState({ questions });
    } catch (error) {
      console.error(error);
      this.setState({ message: 'An error occurred while generating the quiz questions' });
    }
  }

  handleAnswer(event, index) {
    const { questions } = this.state;
    const question = questions[index];

    if (event.target.value === question.correctAnswer) {
      this.setState({ message: 'Good job!' });
    } else {
      this.setState({ message: 'Wrong answer' });
    }
  }

  render() {
    const { book, questions, message } = this.state;

    return (
      <div>
        <Form onSubmit={this.handleSubmit}>
          <Form.Group>
            <Form.Label>Enter the name of a book:</Form.Label>
            <Form.Control type="text" value={book} onChange={this.handleChange} />
          </Form.Group>
          <Button type="submit">Generate Quiz</Button>
        </Form>
        {questions.map((question, index) => (
          <div key={index}>
            <p>{question.question}</p>
             <Form.Group style={{color: '#fff'}}>
      <Form.Check style={{color: '#fff'}}
        type="radio"
        label={question.correctAnswer}
        value={question.correctAnswer}
        onChange={(event) => this.handleAnswer(event, index)}
      />
      <Form.Check style={{color: '#fff'}}
        type="radio"
        label={question.wrongAnswer1}
        value={question.wrongAnswer1}
        onChange={(event) => this.handleAnswer(event, index)}
      />
      <Form.Check style={{color: '#fff'}}
        type="radio"
        label={question.wrongAnswer2}
        value={question.wrongAnswer2}
        onChange={(event) => this.handleAnswer(event, index)}
      />
      <Form.Check style={{color: '#fff'}}
        type="radio"
        label={question.wrongAnswer3}
        value={question.wrongAnswer3}
        onChange={(event) => this.handleAnswer(event, index)}
      />
    </Form.Group>
          </div>
        ))}
        {message && <p style={{color: '#fff'}}>{message}</p>}
      </div>
    );
  }
}


export default QuizApp;

问题原因

所有单选框未设置分组name属性,React-Bootstrap的Form.Check默认会使用相同的name值,导致浏览器将所有单选框识别为同一组,仅渲染最后一组的控件,前面的被覆盖。

修复方案

给每道题的单选框设置唯一分组name,用question-${index}作为name值,确保每道题的单选框属于独立分组,同一题内的单选框name一致。

修改后的render部分代码:

render() {
  const { book, questions, message } = this.state;

  return (
    <div>
      <Form onSubmit={this.handleSubmit}>
        <Form.Group>
          <Form.Label>Enter the name of a book:</Form.Label>
          <Form.Control type="text" value={book} onChange={this.handleChange} />
        </Form.Group>
        <Button type="submit">Generate Quiz</Button>
      </Form>
      {questions.map((question, index) => (
        <div key={index}>
          <p>{question.question}</p>
          <Form.Group style={{color: '#fff'}}>
            <Form.Check style={{color: '#fff'}}
              type="radio"
              name={`question-${index}`}
              label={question.correctAnswer}
              value={question.correctAnswer}
              onChange={(event) => this.handleAnswer(event, index)}
            />
            <Form.Check style={{color: '#fff'}}
              type="radio"
              name={`question-${index}`}
              label={question.wrongAnswer1}
              value={question.wrongAnswer1}
              onChange={(event) => this.handleAnswer(event, index)}
            />
            <Form.Check style={{color: '#fff'}}
              type="radio"
              name={`question-${index}`}
              label={question.wrongAnswer2}
              value={question.wrongAnswer2}
              onChange={(event) => this.handleAnswer(event, index)}
            />
            <Form.Check style={{color: '#fff'}}
              type="radio"
              name={`question-${index}`}
              label={question.wrongAnswer3}
              value={question.wrongAnswer3}
              onChange={(event) => this.handleAnswer(event, index)}
            />
          </Form.Group>
        </div>
      ))}
      {message && <p style={{color: '#fff'}}>{message}</p>}
    </div>
  );
}

补充说明

  • 同一组单选框必须共享相同name,浏览器才能识别它们为一组,保证同一时间仅能选中一个。
  • 不同题目的单选框组需使用不同name,避免跨题单选框互相干扰。
  • 可额外检查API返回的题目数据格式,确保每道题的四个答案字段都存在,避免因数据缺失导致渲染异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 06:00:47