[英]Issue with updating a property that is an array nested inside another array in redux state
所以我一直在浏览有关 redux state 的问题,似乎找不到对我有帮助的问题。 我的问题是我的 state 看起来像这样:
state = {
products = [
{
name: "Example",
description: "Example",
images: ['img1.jpg', 'img2.jpg'],
imgNum: 2,
}
]
}
我想像这样添加到图像和 imgNum 中:
state = {
products = [
{
name: "Example",
description: "Example",
images: ['img1.jpg', 'img2.jpg', 'img3.jpg'],
imgNum: 3,
}
]
}
(这是一个示例,实际代码具有更多属性和项目,但图像和 imgNum 是关注的项目)所以当我尝试更新图像数组或 imgNum 时,我无法做到。 案例如下:
case ADD_IMAGE:
return {
...state,
products: state.products.map((item, i) => {
if(item.name === payload.name) {
return {
...item,
images: [...item.images, payload.image],
imgNum: item.imgNum + 1,
}
}
return item;
});
}
我已经检查以确保在 scope 中 item.images、...item.images 和 item.imgNum 都已定义,并且它们都在 if 语句中返回之前在 console.log'ed 时返回值。 我也尝试了不同的值来代替 ...item.images 但唯一不会引发未定义错误的另一个值是
...state.products[i].images
它也没有导致任何 state 更改。
只是澄清一下-我的代码现在没有任何错误,但是 state 也没有更新。
payload.name 和 payload.image 也返回值,而不是未定义,再次按照 ol console.log 测试。
我尝试的另一件事是在 return 语句之外声明变量,然后在内部使用它们,如下所示:
case ADD_IMAGE:
return {
...state,
products: state.products.map((item, i) => {
if(item.name === payload.name) {
const newArr = [...item.images, payload.image];
const newNum = item.imgNum +1;
return {
...item,
images: newArr,
imgNum: newNum
}
}
return item;
});
}
但是这种出色的编码没有任何结果。
感谢任何帮助,我确信我已经忽略(或完全被)更新 state 的一些细微差别。 让我知道是否需要其他信息。 提前谢谢大家。
编辑以显示操作:
export const uploadImage = (data, image, item) => (dispatch) => {
axios
.post("/products/upload-image", data)
.then(() => {
dispatch({type: ADD_IMAGE, payload: {image: image, name: item.name}})
})
.catch((err) => console.log(err));
};
所以这是我使用的操作,它在文件上传事件中调用。 我知道它有效,因为图像已上传到我的数据库(axios 部分),并且因为 redux-logger 显示文件上传时发生的 ADD_IMAGE 操作。 有效负载图像和名称符合预期,因此一切正常。
而不是这个:
products: state.products.map((item, i) => {
if(item.name === payload.name) {
const newArr = [...item.images, payload.image];
const newNum = item.imgNum +1;
return {
...item,
images: newArr,
imgNum: newNum
}
}
return item;
});
尝试这个:
return {
...state,
products: state.products.map((item, i) =>
item.name === payload.name ? {
...item,
images: item.images.concat(payload.image),
imgNum: item.imgNum +1
} : item,
)
}
感谢提出建议的人。 我想出了一个解决方法,我会坚持在这里。
我不再摆弄减速器的东西,而是更改了动作触发时发送的内容。 我处理了从存储中获取当前图像数组,将其存储为新变量,将我的新图像推送到该新变量数组中,然后将新变量提供给我的操作,这将更新图像数组作为一个整体。 如果不是很清楚,这里有一些片段:
case ADD_IMAGE:
return {
...state,
products: state.products.map((item) => {
if (item.name === payload.name) {
return {
...item,
images: payload.imageArr
};
}
return item;
}),
};
请注意,现在刚刚为图像分配了 payload.imageArr。
在我的组件中,我这样做了:
const imageName = `${Math.round(Math.random() * 100000000).toString()}.jpg`;
const oldArr = currentItem.images;
oldArr.push(imageName);
其中 currentItem 是我商店中的 object ,它是由之前的事件处理程序设置的,并且与 products 数组中的任何其他产品具有所有相同的道具。 imageName 只是我分配图像的随机字符串,然后我将其推送到数组中。 然后在调用操作时传递“oldArr”(请原谅蹩脚的命名,但希望它清楚),并如上所述分配为 payload.imageArr。
感谢 Red Baron、Hemant 和 Ceva Comic 对这个问题的投入!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.