如何在React动态对象的questions数组中创建新动态对象
解决方案
核心修改点
- 给添加问题的函数传入章节索引,明确指定要新增问题的目标章节
- 拆分原有的字段修改逻辑,分别处理章节基础信息和问题内容的更新
- 严格遵循React不可变更新原则,避免直接修改原state对象
完整代码示例
import { useState } from 'react'; export default function QuestionEditor() { const [inputFields, setInputFields] = useState([ { sectionName: "", sectionDesc: "", questions: [{ questionType: "", questionText: "" }], }, ]); // 处理章节名称、描述的修改 const handleSectionChange = (sectionIndex: number, event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => { const updatedSections = [...inputFields]; updatedSections[sectionIndex][event.target.name] = event.target.value; setInputFields(updatedSections); }; // 处理单个问题的题型、内容修改 const handleQuestionChange = (sectionIndex: number, questionIndex: number, event: React.ChangeEvent<HTMLInputElement | HTMLSelectElement>) => { const updatedSections = [...inputFields]; const targetQuestions = [...updatedSections[sectionIndex].questions]; targetQuestions[questionIndex][event.target.name] = event.target.value; updatedSections[sectionIndex].questions = targetQuestions; setInputFields(updatedSections); }; // 给指定章节添加新问题 const handleAddQuestion = (sectionIndex: number) => { const updatedSections = [...inputFields]; updatedSections[sectionIndex].questions = [ ...updatedSections[sectionIndex].questions, { questionType: "", questionText: "" } ]; setInputFields(updatedSections); }; // 保留原有的新增章节功能(若需保留) const handleAddSection = () => { setInputFields([ ...inputFields, { sectionName: "", sectionDesc: "", questions: [{ questionType: "", questionText: "" }], }, ]); }; return ( <div style={{ padding: '20px' }}> {/* 遍历渲染所有章节 */} {inputFields.map((section, sectionIdx) => ( <div key={sectionIdx} style={{ marginBottom: '20px', padding: '15px', border: '1px solid #eee' }}> <div style={{ marginBottom: '10px' }}> <input name="sectionName" value={section.sectionName} onChange={(e) => handleSectionChange(sectionIdx, e)} placeholder="章节名称" style={{ marginRight: '10px' }} /> <textarea name="sectionDesc" value={section.sectionDesc} onChange={(e) => handleSectionChange(sectionIdx, e)} placeholder="章节描述" rows={2} style={{ width: '300px' }} /> </div> {/* 渲染当前章节的所有问题 */} {section.questions.map((question, qIdx) => ( <div key={qIdx} style={{ margin: '10px 0', padding: '10px', border: '1px dashed #ccc' }}> <select name="questionType" value={question.questionType} onChange={(e) => handleQuestionChange(sectionIdx, qIdx, e)} style={{ marginRight: '10px' }} > <option value="">选择题型</option> <option value="single">单选题</option> <option value="multiple">多选题</option> <option value="text">简答题</option> </select> <input name="questionText" value={question.questionText} onChange={(e) => handleQuestionChange(sectionIdx, qIdx, e)} placeholder="输入问题内容" style={{ width: '300px' }} /> </div> ))} {/* 当前章节的添加问题按钮 */} <button onClick={() => handleAddQuestion(sectionIdx)}>给本章节添加问题</button> </div> ))} {/* 新增章节按钮 */} <button onClick={handleAddSection}>添加新章节</button> </div> ); }
关键说明
- 精准定位操作对象:通过
sectionIdx(章节索引)和qIdx(问题索引),确保每次修改或新增操作都指向正确的目标 - 不可变更新:所有state修改都通过复制原数组/对象生成副本,修改副本后再更新state,避免React状态更新异常
- 逻辑拆分:将章节和问题的修改逻辑分开,代码可读性和可维护性更强
内容的提问来源于stack exchange,提问作者Umarkhon
相关产品推荐
相关产品推荐

