繁体   English   中英

更新嵌套在 redux state 中的另一个数组中的数组属性时出现问题

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM