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
相关产品推荐
相关产品推荐

