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

React状态对象中数组元素添加报错及正确实现咨询

问题解决与正确实现方法

报错原因分析

  1. "data.sections is not iterable" 报错
    你的SecondStep组件接收参数的方式错误:React组件的参数是一个props对象,而非独立的data和setData。原写法中data实际指向整个props对象,导致data.sections不存在,使用扩展运算符时自然无法迭代。

  2. "Cannot read properties of undefined (reading 'push')" 报错

    • 同样可能存在props传递错误导致sections为undefined的情况;
    • 直接执行let copyData = data是浅拷贝,本质仍在修改原状态对象,违反React状态不可变的原则,且若sections未正确初始化会触发该报错。

正确添加sections元素的实现

修复组件props接收

首先修正SecondStep的props解构方式:

export default function CreateStepper() {
  const [data, setData] = useState({
    name: "",
    desc: "",
    sections: [],
  });

  return (
    <>
      <SecondStep data={data} setData={setData} />
    </>
  );
}

// 注意这里要解构props对象
function SecondStep({ data, setData }) {
  const newSection = {
    sectionName: "Hdsd",
    sectionDesc: "dsdsd",
    question: [],
  };

  // 方式1:扩展运算符更新(处理边界情况)
  const handleAddSection = () => {
    setData({
      ...data,
      // 用data.sections || []确保sections始终是数组,避免undefined报错
      sections: [...(data.sections || []), newSection]
    });
  };

  // 方式2:函数式更新(推荐,解决状态依赖问题)
  // const handleAddSection = () => {
  //   setData(prevData => ({
  //     ...prevData,
  //     sections: [...prevData.sections, newSection]
  //   }));
  // };

  return (
    <Box>
      <button onClick={handleAddSection}>添加章节</button>
    </Box>
  );
}

向sections元素的question数组添加对象

若要给指定索引的section添加问题,需遵循不可变更新原则,逐层拷贝对象和数组:

const handleAddQuestion = (sectionIndex) => {
  const newQuestion = {
    title: "新问题标题",
    content: "问题内容"
  };

  // 使用函数式更新确保拿到最新状态
  setData(prevData => {
    // 1. 拷贝整个sections数组
    const updatedSections = [...prevData.sections];
    // 2. 拷贝目标section对象,避免修改原对象
    const targetSection = updatedSections[sectionIndex];
    const updatedSection = {
      ...targetSection,
      // 3. 扩展原question数组并添加新问题
      question: [...targetSection.question, newQuestion]
    };
    // 4. 替换数组中的目标section
    updatedSections[sectionIndex] = updatedSection;
    // 5. 返回新的data对象
    return {
      ...prevData,
      sections: updatedSections
    };
  });
};

关键注意事项

  • 组件接收props时,必须通过解构或props.data的方式访问传递的值;
  • 永远不要直接修改useState返回的原状态对象,必须生成新的对象/数组来更新状态;
  • 当新状态依赖旧状态时,优先使用函数式更新(setData(prev => ...)),避免状态快照过期导致的错误;
  • 处理边界情况,确保sections始终是数组,避免undefined引发的报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 21:45:28