Home > other >  Uploading Multiple Images in React and Redux
Uploading Multiple Images in React and Redux

Time:03-16

I'm trying to upload multiple images and I'm passing the image one by one to the API so once an image will be uploaded, it can already be displayed without waiting for other images to finish uploading.

My problem is I have a loader and I display it when images are uploading. If some images are already finished uploading while other are still uploading, the loader disappears already?

Component

{
  isImagesUploading && (
    <Box sx={{ width: "100%" }}>
      <LinearProgress />
    </Box>
  );
}



const onUploadImage = (files) => {
  const fileList = Array.from(files);
  const images = fileList.map((image) => {
    ...
  });

  uploadImages(newImages);
};

Reducer

case UPLOAD_IMAGES_REQUEST:
      return {
        ...state,
        isImagesUploading: true,
      }
case UPLOAD_IMAGES_REQUEST:
      return {
        ...state,
        isImagesUploading: false,
        images: action.payload
      }

Action

export const uploadImages =
  ({ images }) =>
  async (dispatch) => {
    images.forEach(async (image) => {
      const formData = new FormData();
      formData.append(image.name, image.imageFile);

      try {
        dispatch({
          type: UPLOAD_IMAGES_REQUEST,
        });

        const response = await axios.post("http://test.com", formData);

        dispatch({
          type: UPLOAD_IMAGES_SUCCESS,
          payload: [...(images || [])],
        });
      } catch (error) {
        dispatch({
          type: UPLOAD_IMAGES_FAILURE,
        });
      }
    });
  };

CodePudding user response:

You could track a count of pending uploads. Any count > 0 show any loading indicator in your UI.

Example:

case UPLOAD_IMAGES_REQUEST:
  return {
    ...state,
    imageUploadCount: state.imageUploadCount   1,

case UPLOAD_IMAGES_REQUEST:
  return {
    ...state,
    imageUploadCount: state.imageUploadCount - 1,
    images: action.payload
  };

case UPLOAD_IMAGES_FAILURE:
  return {
    ...state,
    imageUploadCount: state.imageUploadCount - 1,
  };

...

export const uploadImages = ({ images }) => (dispatch) => {
  images.forEach(async (image) => {
    const formData = new FormData();
    formData.append(image.name, image.imageFile);

    try {
      dispatch({ type: UPLOAD_IMAGES_REQUEST });

      const response = await axios.post("http://test.com", formData);

      dispatch({
        type: UPLOAD_IMAGES_SUCCESS,
        payload: [...(images || [])],
      });
    } catch (error) {
      dispatch({ type: UPLOAD_IMAGES_FAILURE });
    }
  });
};

In your ui, create a state selector function to read the count and derive if any loading indicator should be displayed.

Example:

const isUploading = useSelector(state => state.images.imageUploadCount > 0);

...

return (
  <>
    {isUploading && <LoadingSpinner />}
    ...
  </>
);
  • Related