javascript - 未捕获的类型错误:更新状态时无法分配给只读属性
问题描述
我正在尝试重现我原来的问题。
我有两个处于反应状态Array1
的数组,它们是来自数据库的原始数组,并且Array2
是处于状态的更新数组。
目标是仅更新已更改rate
而不是quantity
(和其他属性)回数据库,因此我需要使用数组对象中的速率值更新对象中的basicrecipe
速率recipeBasicRecipe
值,以匹配 basicrecipe
与对象匹配的对象在recipeBasicRecipe
.
运行代码时出现此错误,请求帮助
Error:Uncaught TypeError: Cannot assign to read only property
let basicRecipes = [
{
id: 1,
name: IceCream,
details: [{ id: "12", name: "milk", quantity: "50", rate: "100" },
{ id: "13", name: "cream", quantity: "50", rate: "300" }]
},
{
id: 2,
name: Coffee,
details: [{ id: "14", name: "Coffee bean", quantity: "60", rate: "200" },
{ id: "15", name: "water", quantity: "60", rate: "300" }]
},
{
id: 3,
name: Tea,
details: [{ id: "16", name: "Tea leaf", quantity: "50", rate: "700"
}]
}]
let recipeBasicRecipe = [
{
id: 1,
name: IceCream,
details: [{ id: "12", name: "milk", quantity: "50", rate: "500" },
{ id: "13", name: "cream", quantity: "50", rate: "700" }]
},
{
id: 2,
name: Coffee,
details: [{ id: "14", name: "Coffee bean", quantity: "60", rate: "800" },
{ id: "15", name: "water", quantity: "60", rate: "8000" }]
}
];
let r = basicRecipe;
let Array2 = recipeBasicRecipes;
r = r.map(item => {
let element = Array2.find(e => e.id == item.id);
if (element) {
item.details = item.details.map(e => {
let detail = element.details.find(d => d.id == e.id);
if (detail) {
e.rate = detail.rate;
}
return e;
});
}
return item;
});
console.log(r);
const initialState = {
basicRecipe: [],
recipeBasicRecipes: [],
};
const [state, dispatch] = useReducer(recipeManagementReducer, initialState);
我正在执行此代码的功能
const onSubmit = e => {
e.preventDefault();
/**
*
setShowLoader();
updateawMateris(state.recipeRawMaterials);
* */
let r = state.basicRecipe;
let Array2 = state.recipeBasicRecipes;
r = r.map(item => {
let element = Array2.find(e => e._id == item._id);
if (element) {
item.details = item.details.map(e => {
let detail = element.details.find(d => d._id == e._id);
if (detail) {
e.rate = detail.rate;
}
return e;
});
}
return item;
});
在玩耍时,我更改了返回以使其不可变,因为这是导致错误的原因。
这是片段,唯一的问题是这也会返回配方中数量的变化,我该如何避免
let r = [...state.basicRecipe];
let Array2 = [...state.recipeBasicRecipes];
r = r.map(item => {
let element = Array2.find(e => e._id === item._id);
if (element) {
item.details = item.details.map(e => {
let detail = element.details.find(d => d._id === e._id);
if (detail) {
return {
...e,
rate: detail.rate
};
}
return e;
});
}
return item;
});
console.log(r);
解决方案
好吧,在为你做了一些研究之后,我意识到你返回的数据中的一些属性是不可写的。
例如错误:
无法分配给对象“#”的只读属性“速率”
发生是因为rate
ore
中的itemmap
不可变。为了使其工作,您必须创建该数据的副本,而不是在此处将其引用存储在您的变量中:
let r = state.basicRecipe;
let Array2 = state.recipeBasicRecipes;
r
并且Array2
只是对您的状态属性的引用。
您可能想要制作该数据的新副本。像这样:
let r = [...state.basicRecipe];
let Array2 = [...state.recipeBasicRecipes];
然后运行您的代码并修改您想要更改的属性。
这是您的场景的最小复制,我没有收到任何错误。请检查并建议?
class Something extends React.Component{
state = {
basicRecipes : [
{
id: 1,
name: "IceCream",
details: [{ id: "12", name: "milk", quantity: "50", rate: "100" },
{ id: "13", name: "cream", quantity: "50", rate: "300" }]
},
{
id: 2,
name: "Coffee",
details: [{ id: "14", name: "Coffee bean", quantity: "60", rate: "200" },
{ id: "15", name: "water", quantity: "60", rate: "300" }]
},
{
id: 3,
name: "Tea",
details: [{ id: "16", name: "Tea leaf", quantity: "50", rate: "700"
}]
}],
recipeBasicRecipe : [
{
id: 1,
name: "IceCream",
details: [{ id: "12", name: "milk", quantity: "50", rate: "500" },
{ id: "13", name: "cream", quantity: "50", rate: "700" }]
},
{
id: 2,
name: "Coffee",
details: [{ id: "14", name: "Coffee bean", quantity: "60", rate: "800" },
{ id: "15", name: "water", quantity: "60", rate: "8000" }]
}
]
};
constructor(props)
{
super(props);
this.performSomeAction = this.performSomeAction.bind(this);
}
performSomeAction()
{
let r = [...this.state.basicRecipes];
let Array2 = [...this.state.recipeBasicRecipe];
return r.map(item => {
let element = Array2.find(e => e.id === item.id);
let tempItem = {...item}; // Make a mutable copy of Item
if (element) {
tempItem.details = item.details.map(e => {
let detail = element.details.find(d => d.id === e.id);
let tempE = {...e}; // Make a mutable copy of e
if (detail) {
tempE.rate = detail.rate;
}
return tempE;
});
}
return tempItem;
});
}
render()
{
console.log(this.performSomeAction());
return(
<h1>Code Runs</h1>
);
}
}
ReactDOM.render(<Something />,
document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.production.min.js"></script>
<div id="root"></div>
推荐阅读
- javascript - 初始搜索后无法再次搜索
- prolog - 比较二叉树 SWI Prolog 中的节点
- python - 如何递归地抓取网页以检查python中是否有新的pdf文件?
- c++ - 如何使用 libcurl 将图像上传到 Twitter?
- mysql - Node JS, Express MySQL ES_PARSE_ERROR...“在'?,?,?,?,?附近使用正确的语法”
- reactjs - 子组件不会通过更改道具来更新
- mysql - 即使使用错误的凭据也能成功登录?
- groovy - 在 JMeter 的 JSR223 断言中获取所有以前的采样器结果(重定向)
- typescript - Angular 8 按值或引用绑定?
- python - Django 3.0 中自定义用户模型的身份验证