1

I am trying to select multiple images, and the images are being selected and stored in the state, but only one image is displayed.Below is the code for the same

//Selecting the image and displaying the image

 <div className="md-form mb-5">
          <input type="file" id="form29" name='images' onChange={e => pickImage(e)} className="form-control validate" multiple hidden/>
          <button className="btn btn-outline-dark btn-sm" onClick={e => selectImage(e)}>Pick Image</button>
        </div>
                <div className="row text-center">
                    {image.length > 0 ?
                    image.map(img => (
                        <div className="col-md-4" key={img.url}>
                            <img src={img.url} alt={img.name} className="img-fluid"/>
                            <span style={{cursor: 'pointer'}}>
                            <i class="far fa-trash-alt" onClick={e => deleteImage(img.name, e)}></i>
                            </span>
                        </div>
                    )) : <p>No Images Picked</p>}
                </div>

//Defining the state

const [addDiary, setAddDiary] = useState({date: null, content: null, images: []});
const [ image, setImage ] = useState([]);

//Defining the methods to store and delete image

const selectImage = (e) => {
        document.getElementById('form29').click();
    }

    const deleteImage = (name, e) => {
        const remainingImage = image.filter(img => {return img.name !== name});
        setImage(remainingImage);
        const remainingImageState = addDiary.images.filter(img => 
            {
            return img.name !== name});
        setAddDiary({...addDiary, images: remainingImageState });
    }

    const pickImage = (e) => {
       console.log(e, 'e obj')
        for(const file of e.target.files) {
            const reader = new FileReader();
            reader.onload = (e) => {

               setImage([...image, {url: URL.createObjectURL(file), name: file.name}]);
               console.log(e.target.name)
               setAddDiary({ ...addDiary, images: [...addDiary.images, file]});
              };
               reader.readAsDataURL(file);
            }

        }

2 Answers 2

1

The issue here is that you are updating the image each time is loaded, so you should first load all images into cache an finally update the state, you can do by putting this code

const pickImage = (e) => {
  console.log(e, 'e obj');
  const limitImages = e.target.files.length;
  let count = 0;
  const images = [];
  for(const file of e.target.files) {
    const reader = new FileReader();
    reader.onload = (e) => {
      images.push({ url: URL.createObjectURL(file), name: file.name });
      count++;

      if (count === limitImages) {
        // here all images are loaded, so update the state
        setImage(images);
        setAddDiary({ ...addDiary, images: addDiary.images.concat(images)});
      }      
    };
    reader.readAsDataURL(file);
  }
}

Remember you should handle the error event too, too notify the user that was an error

So you can avoid the selectImage method to trigger onClick event into the input, just by adding an id to your input file and use a label to trigger the event, like this:

<div className="md-form mb-5">
  <input type="file" id="form29" name='images' onChange={e => pickImage(e)} className="form-control validate" multiple hidden id="file-picker" />
  <button className="btn btn-outline-dark btn-sm" onClick={e => selectImage(e)}>
    <label id={'file-picker'}>
      Pick Image
    </label>
  </button>
</div>

I hope it can help you

Sign up to request clarification or add additional context in comments.

Comments

0

Your key for you map is set as an object. Try setting as the image name to avoid ommitting. React cannot tell the keys apart if they are objects:

<div className="col-md-4" key={img.name}>
  <img src={img} alt={img} className="img-fluid"/>
  <span style={{cursor: 'pointer'}}>
  <i class="far fa-trash-alt" onClick={e => deleteImage(img.name, e)}></i>
  </span>
</div>

1 Comment

it was just a typo, but still the images are not being displayed, else everything is working, just if select more than 1 images, only one image will be stored in image state and displayed, else are not being displayed or stored in the state

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.