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

React中Cannot add property 1, object is not extensible错误求助

React中向对象数组子数组push元素时出现"Cannot add property 1, object is not extensible"错误的解决方案

错误原因分析

这个错误的核心是你操作的emails数组是不可扩展(non-extensible)的对象。常见触发场景是:

  • 数据来自外部不可变源(比如API响应被冻结、第三方库返回的不可修改对象、或者直接引用了不可变状态中的数据)
  • 看你的useEffect代码,直接将selectedRow[k]赋值给prop.emails,如果selectedRow里的数组本身是不可扩展的,后续对这个数组执行push操作就会触发错误。虽然addEmail里复制了RegionalList数组,但数组内的对象是浅拷贝,emails数组仍指向原来的不可扩展引用。

修复方案

1. 修复useEffect中的数据赋值逻辑

不要直接把selectedRow[k]赋值给prop.emails,而是创建新的可扩展数组,同时避免直接修改原状态对象:

useEffect(() => {
    if (selectedRow) {
      setData({
        regionName: selectedRow['regionName'],
        marketName: selectedRow['marketName'],
        subRegionName: selectedRow['subRegionName'],
      });

      // 对原数组每个对象做浅拷贝,确保emails是新的可扩展数组
      const regional = RegionalList.map(prop => {
        const newProp = {...prop};
        for (const k in selectedRow) {
          if (newProp.column === k) {
            // 用展开运算符生成新数组,替代直接赋值
            newProp.emails = selectedRow[k] ? [...selectedRow[k]] : [];
          }
        }
        return newProp;
      });
      setRegionalList(regional);
    }
  }, [selectedRow]);

2. 优化addEmail函数的状态更新方式

遵循React不可变状态原则,避免直接修改原数组,而是创建新对象和新数组来更新状态:

const addEmail = (id: number) => {
    const regionalList = RegionalList.map(prop => {
      if (prop.id === id) {
        return {
          ...prop,
          emails: [
            ...prop.emails,
            {
              emailAddress: '',
              firstName: '',
              lastName: '',
              id: Math.floor(Math.random() * 999),
              fetching: false,
            }
          ]
        };
      }
      return prop;
    });
    setRegionalList(regionalList);
  };

3. 修复setEmailValue函数的状态更新逻辑

避免直接修改原数组元素,通过复制数组和对象来更新状态,防止丢失原有属性:

const setEmailValue = (event: any, regionalId: number, index: number) => {
    setRegionalList((prevState) => {
      return prevState.map(prop => {
        if (prop.id === regionalId) {
          // 复制emails数组,修改指定索引的元素
          const newEmails = [...prop.emails];
          newEmails[index] = { 
            ...newEmails[index], // 保留原对象的其他属性
            emailAddress: event.target.value, 
            id: null 
          };
          return { ...prop, emails: newEmails };
        }
        return prop;
      });
    });
  };

额外建议

  • 始终遵循React不可变状态原则:不直接修改状态中的对象/数组,通过创建新对象/数组完成更新,这能避免绝大多数不可变性相关问题
  • 如果数据来自外部API,可在接收时做一次深拷贝(比如JSON.parse(JSON.stringify(data))),确保所有嵌套对象都是可扩展的

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 04:20:55