React报错:无法给数组对象的只读属性'0'赋值,求原因及解决办法
报错原因及解决思路
报错原因
- 直接修改原state对象/数组:你在代码里直接修改了
prevState中的prop.emails[index],React要求state是不可变的,直接修改原state会导致状态更新异常;如果初始的RegionalListData是被冻结状态(比如用Object.freeze处理过),或者IRegionalList类型中emails被定义为只读数组(如readonly { emailAddress: string; id: number | null }[]),就会触发"无法给只读属性'0'赋值"的错误。 - 类型定义限制:如果
IRegionalList的emails属性被标记为只读,TypeScript会强制阻止你直接通过索引修改数组元素,因为只读数组不允许这类赋值操作。
解决思路
严格遵循React状态不可变更新原则,通过创建新的对象和数组来替换原有内容,而非直接修改:
修改后的代码示例:
const [RegionalList, setRegionalList] = useState<IRegionalList[]>(RegionalListData); 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] = { emailAddress: event.target.value, id: null }; // 返回全新的对象,不修改原prop return { ...prop, emails: newEmails }; } return prop; }); }); };
关键要点
- 永远不要直接修改
prevState中的任何属性,所有状态更新都要通过创建新的对象/数组完成 - 如果
IRegionalList的emails是只读类型,通过扩展运算符(...)创建新数组,既能绕过只读限制,又符合TypeScript的类型检查要求
内容的提问来源于stack exchange,提问作者Tim Launders
相关产品推荐
相关产品推荐

