Nats E
Nats E

Reputation: 63

Upload multiple images and save to array in React JS

Need help getting a full list of pictures that are uploaded with the codes below then save it to an array:

const [pictures, setPictures] = useState([{
        data: [],
        url: ""
    }])

    const handleImageUpload = (e) => {

        [...e.target.files].forEach(file => {
            console.log("file >>> ", file)

                 setPictures([
                    ...pictures,
                    {
                        data: file,
                        url: URL.createObjectURL(file)
                    }
                ])

                console.log("pictures >> ", pictures)
            })
    }

Whenever I show a preview of the images, it only shows the last image that was uploaded so my guess is the input:file is running async

<div className="post__pictures">
    <input type="file" multiple 
        onChange={handleImageUpload}
        accept="image/*"
    />

        {pictures?.map(pic => (
            <img src={pic.url} />
        ))}
</div>

Below are the results in the console log

    file >>>  
        File {name: "software-development-coding-process-concept-260nw-1483883831.png", lastModified: 1609189641927, lastModifiedDate: Tue Dec 29 2020 01:07:21 GMT+0400 (Gulf Standard Time), webkitRelativePath: "", size: 14722, …}
        Post.js:51 
    
    pictures >>  
        [{…}]
        0: {data: Array(0), url: ""}
        length: 1
        __proto__: Array(0)
        Post.js:41 

file >>>  
        File {name: "software-language-programmer-avatar-vector-17866088.jpg", lastModified: 1609301370464, lastModifiedDate: Wed Dec 30 2020 08:09:30 GMT+0400 (Gulf Standard Time), webkitRelativePath: "", size: 131625, …}
        Post.js:51 
    
    pictures >>  
        [{…}]
        0: {data: Array(0), url: ""}
        length: 1
        __proto__: Array(0)
        Post.js:41 

file >>>  
        File {name: "stock-market-chart-600w-252511228.webp", lastModified: 1609532996651, lastModifiedDate: Sat Jan 02 2021 00:29:56 GMT+0400 (Gulf Standard Time), webkitRelativePath: "", size: 62182, …}
        Post.js:51 
    
    pictures >>  
        [{…}]
        0: {data: Array(0), url: ""}
        length: 1
        __proto__: Array(0)

Upvotes: 0

Views: 5263

Answers (1)

Robin
Robin

Reputation: 5427

Its happen because you setState inside of loop. Update your handleImageUpload like this, it works fine for me.

If you setState inside of loop, DOM will re-render in every setState. Thats why it shows the last image.

const handleImageUpload = e => {
  const tempArr = [];

  [...e.target.files].forEach(file => {
    console.log("file >>> ", file);

    tempArr.push({
      data: file,
      url: URL.createObjectURL(file)
    });

    console.log("pictures >> ", pictures);
  });

  setPictures(tempArr);
};

Upvotes: 1

Related Questions