Redux Added Array of Object Inside Another Aray in React

Viewed 99

I have here products that may have one or more than one images. Depending on the productCode. If the productCode is the they belong to the same product. productCode could be found on the filename of the images, its after the first underscore. For instance if the filename is AA_BB_CC.jpg. The productCode is BB.

You can check samples images in my codesandbox.

So if images have the same productCode, it should add up to the product. My problem is on this part. Adding images of product with the same productCode.

Here's the codesandbox CLICK HERE

CODE

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

EXPECTED OUTPUTenter image description here

Response of expected output

enter image description here

2 Answers

I see you already do the string splitting in the file uploader when you create the file image objects. In this case you just need to check the generated productCode of the image object payloads to see if it is already contained in the products array. If it isn't then generate the new "product" state object and add the image to the array, otherwise apply the immutable update pattern to shallow copy state and append the new file object.

Since each product in the action payload could potentially belong to different products you'll need to iterate this array in order to determine where each new product should be merged.

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

Edit redux-added-array-of-object-inside-another-aray-in-react

enter image description here

You can do this with immer

the reducer can use the produce function from immer to push new images to the correct "proudctImages" array according to the "productCode"

import produce from 'immer';

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

You also need the productCode information for the new images.

"findProductWithProductCode" just loop through draftProducts and find the array element which "productCode" = action.payload.productCode

Related