Search code examples
reactjsfrontendintegration

(React) How to preview input images before uploding in react?


enter image description here I have these five input fields and below are their previews BUT only the last upload image is being displayed I want to display all five images

` this is what my current code looks like

 const [preview, setFilepre] = useState();
  function fileSelectedHandler(e) {
    let file = e.target.files[0];
    console.log(e.target.name);
    setFilepre(URL.createObjectURL(e.target.files[0]));
    setMemberData({
      ...memberData,
      [e.target.name]: {
        data: e.target.files[0],
        contentType: e.target.files[0].type,
      },
    });
  }

`

CContainer className="form-image-cont " >
              <CFormText>Images</CFormText>
        <img src={preview} className="image-input"/>
        <img src={preview} className="image-input"/>
        <img src={preview} className="image-input"/>
        <img src={preview} className="image-input"/>
        <img src={preview} className="image-input"/>
        </CContainer>

Solution

  • You're using just one state for all of your images. So always the next image you upload, replaces with the previous one.

    In order to fix the problem, you should use an array as your state and pass the index of the image you're uploading to the function like this:

    const [previewImages, setPreviewImages] = useState(Array(5).fill(null));
    function fileSelectedHandler(e, index) {
      let file = e.target.files[0];
      const newPreviewImages = [...previewImages];
      const imageSrc = URL.createObjectURL(e.target.files[0]);
      /* insert image at the index of the array */
      newPreviewImages.splice(index, 0, imageSrc);
      setPreviewImages(newPreviewImages);
      setMemberData({
        ...memberData,
        [e.target.name]: {
          data: e.target.files[0],
          contentType: e.target.files[0].type,
        },
      });
    }
    
    CContainer className="form-image-cont " >
      <CFormText>Images</CFormText>
      {previewImages.map((previewImage) => previewImage ? <img src={previewImage} className="image-input"/> : null)}
    </CContainer>
    

    Read more about splice.

    Update:

    You can replace the existing preview image by checking if the index of the preview image is null or not in the array and then decide to replace it or add it like this:

    function fileSelectedHandler(e, index) {
      let file = e.target.files[0];
      const newPreviewImages = [...previewImages];
      const imageSrc = URL.createObjectURL(e.target.files[0]);
      if(newPreviewImages[index] === null) {
        /* insert image at the index of the array */
        newPreviewImages.splice(index, 0, imageSrc);
      } else {
        /* replace the previous image at index */
        newPreviewImages[index] = imageSrc;
      }
      setPreviewImages(newPreviewImages);
      setMemberData({
        ...memberData,
        [e.target.name]: {
          data: e.target.files[0],
          contentType: e.target.files[0].type,
        },
      });
    }