Redux 在 React 中将对象数组添加到另一个数组中

Redux Added Array of Object Inside Another Aray in React

我这里的产品可能有一张或多张图片。取决于产品代码。 如果 productCode 是它们属于同一产品。 productCode 可以在图像的文件名中找到,它位于第一个下划线之后。例如,如果文件名是 AA_BB_CC.jpg。 productCode 是 BB.

您可以在我的codesandbox中查看示例图片。

因此,如果图像具有相同的 productCode,它应该加起来就是产品。我的问题在这部分。添加具有相同产品代码的产品图片。

这是codesandbox CLICK HERE

代码

  return {
    ...state,
    products: [...state.products, ...action.payload]
  };

预期输出

预期输出的响应

您可以使用 immer

reducer 可以根据“productCode”使用 immer 的 produce 函数将新图像推送到正确的“proudctImages”数组

import produce from 'immer';

...
return {
  ...state,
  products: produce(state.products, draftProducts => {
    const product = findProductWithProductCode(draftProducts, action.payload.productCode);
    product.productImages.push(...action.payload.productImages)
  })
};

您还需要新图像的产品代码信息。

"findProductWithProductCode" 只是遍历 draftProducts 并找到 "productCode" = action.payload.productCode

的数组元素

我看到您在创建文件图像对象时已经在文件上传器中进行了字符串拆分。在这种情况下,您只需要检查生成的 productCode 图像对象负载,看看它是否已包含在 products 数组中。如果不是,则生成新的“产品”状态对象并将图像添加到数组,否则将不可变更新模式应用于浅拷贝状态并附加新文件对象。

由于操作负载中的每个产品可能属于不同的产品,因此您需要迭代此数组以确定应合并每个新产品的位置。

case appConstants.UPLOAD_PRODUCT_SUCCESS:
  // (1) iterate the product images array
  return action.payload.reduce(
    (
      state,
      {
        productCode,
        productName,
        productCategory,
        imageFile,
        imageFileName
      }
    ) => {
      // (2) Check if the product is already in state
      const shouldUpdate = state.products.some(
        (product) => product.productCode === productCode
      );

      // (3a) If we just need to return updated state with added new image
      if (shouldUpdate) {
        return {
          ...state,
          // (4) shallow copy the products array
          products: state.products.map((product) =>
            product.productCode === productCode
              // (4b) If this is the matching product, shallow copy product
              // append a new image file object with new id
              ? {
                  ...product,
                  productImages: product.productImages.concat({
                    id: uuidV4(),
                    imageFile,
                    imageFileName
                  })
                }
              // (4b) copy forward existing product object
              : product
          )
        };
      }

      // (3b) Create a new product object and initially populate images array
      return {
        ...state,
        products: state.products.concat({
          productCode,
          productName,
          productCategory,
          productExisting: true,
          productImages: [
            {
              id: uuidV4(),
              imageFile,
              imageFileName
            }
          ]
        })
      };
    },
    state
  );