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

