在redux状态下更新嵌套在另一个数组中的数组属性的问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在redux状态下更新嵌套在另一个数组中的数组属性的问题相关的知识,希望对你有一定的参考价值。

所以我一直在浏览这里的关于redux状态的问题,但似乎找不到一个能帮助我的问题。我的问题是,我的状态是这样的。

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;
    );
  

我已经检查过了,确保在这个范围内 item.images, ...item.images, 和 item.imgNum 都被定义了,而且当 console.log'ed 在 if 语句的 return 之前,它们都返回了值。我还尝试了不同的值来代替...item.images,但是唯一一个没有抛出未定义错误的是...item.images。

...state.products[i].images

而且也没有导致任何状态变化。

我只想澄清一下--我的代码就像现在这样,我没有得到任何错误,但状态也没有更新。

payload.name和payload.image也返回了值,而且不是未定义的,再次根据ol console.log测试。

我还尝试了另一件事,就是在返回语句之外声明变量,然后像这样在里面使用。

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;
    );
  

但是这段精彩的编码却没有任何结果。

任何帮助都是感激的,我肯定我忽略了(或完全被)更新状态的一些细微差别。如果需要更多的信息,请告诉我 先谢谢大家。

编辑显示操作。

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,
    )
  
另一答案

感谢那些提出建议的人 我想出了一个变通的办法,我将坚持在这里。

我没有再去摆弄reducer的东西,而是改变了动作启动时发送的内容。我处理了从商店获取当前图像数组,将其存储为一个新的变量,将我的新图像推送到新的变量数组上,然后将新的变量提供给我的操作,从而更新整个图像数组。下面是一些片段,以防不是很清楚。

    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是我的商店里的一个对象 它是由早期的一个事件处理程序设置的 并且和产品数组里的其他产品一样拥有相同的道具 imageName是我给图片分配的随机字符串 然后我就把它推到数组里了 然后,当调用动作时,"oldArr"(原谅我的命名很蹩脚,但想让它更清晰)被传递,并被分配为上面提到的 payload.imageArr。

感谢Red Baron、Hemant和Ceva Comic对这个问题的意见!

以上是关于在redux状态下更新嵌套在另一个数组中的数组属性的问题的主要内容,如果未能解决你的问题,请参考以下文章

将项目添加到 redux-toolkit 中的嵌套数组

如何在 ReactJs Redux 中删除/设置状态数组的“null”嵌套属性?

在redux中更新深层嵌套数组

Redux Dispatch - 从数组/不正确的数组长度输出中删除项目

在 React/Redux reducer 中,如何以不可变的方式更新嵌套数组中的字符串?

在 Redux 状态下更新单个值