React使用useReducer修改样式时报Cannot assign to read only property 'color'错误
问题原因
- 你使用
[...listt.list]对数组做的是浅拷贝,仅复制了数组容器本身,数组内的元素对象、以及元素下的style对象都还是和原状态共享同一个引用 - 当你将
listt.list[0].style作为prop传给<h2>的style属性后,React会自动冻结这个对象为只读,防止外部直接修改prop引发状态不可预期的问题,此时你直接修改clone[0].style.color就会触发cannot assign to read only property的报错 - 你移除
<h2>的style属性后,style对象没有被React冻结,直接修改就不会触发报错,但这种直接修改原状态引用的写法本身不符合React不可变数据的规范,属于不严谨的写法
解决方法
修改reducer中的更新逻辑,遵循React不可变数据原则,对需要修改的层级全量新建引用,不要直接修改原有对象:
import React, { useReducer } from "react"; function Texting() { const state = { list: [{ name: "I am awesome", style: { color: "purple" } }], }; function reducer(listt, action) { switch (action) { case "toggle": const clone = [...listt.list]; // 对需要修改的数组元素、style对象逐层新建引用,不修改原有对象 clone[0] = { ...clone[0], style: { ...clone[0].style, color: "red" } }; return { ...listt, list: clone }; default: return listt; } } const [listt, dispatch] = useReducer(reducer, state); return ( <div> Color = {listt.list.map((x) => x.style.color)} <button onClick={() => dispatch("toggle")}>toggle!</button> <h2 style={listt.list[0].style}> 报错原因:TypeError: Cannot assign to read only property 'color' of object </h2> </div> ); } export default Texting;
内容的提问来源于stack exchange,提问作者longan177
相关产品推荐
相关产品推荐

