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

如何在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>
  );
}

关键说明

  1. 精准定位操作对象:通过sectionIdx(章节索引)和qIdx(问题索引),确保每次修改或新增操作都指向正确的目标
  2. 不可变更新:所有state修改都通过复制原数组/对象生成副本,修改副本后再更新state,避免React状态更新异常
  3. 逻辑拆分:将章节和问题的修改逻辑分开,代码可读性和可维护性更强

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 09:33:21