Rajan Baliwal
Rajan Baliwal

Reputation: 1

How can I preview of multiple images in react? I'm able to get the preview of one but not multiple

import React, { useState, useRef } from 'react';

import './ImageUpload.css';

const App = () => {
const [preview, setPreview] = useState();

const changedHandler = event => {
    let files = event.target.files;
    let reader;
    let res = []; 

    for (var i = 0; i < files.length; i++) {
        var file = files[i];
        reader = new FileReader();
        reader.readAsDataURL(file); 

        reader.onload = event => {
            setPreview(event.target.result);
        }
    }     
}

return (
    <div>
    <input
        type="file"
        name="file"
        multiple
        onChange={changedHandler} />

        {preview && <div className="image-upload__preview">
            <img src={preview} alt="Preview" />
        </div>}

    </div>
)
}

export default App;

Upvotes: 0

Views: 1344

Answers (2)

Rajan Baliwal
Rajan Baliwal

Reputation: 1

Here's the final solution to this question of Previewing multiple images in React before uploading.

$

import React, { useState } from 'react';

import './ImageUpload.css';

const App = () => {
    const [preview, setPreview] = useState([]);
    const fileobj= [];

    const changedHandler = event => {
        let files = event.target.files;
        fileobj.push(files);
        let reader;

        for (var i = 0; i < fileobj[0].length; i++) {
            reader = new FileReader();
            reader.readAsDataURL(fileobj[0][i]);
            reader.onload = event => {
            preview.push(event.target.result);   // update the array instead of replacing the entire value of preview

            setPreview([...new Set(preview)]); // spread into a new array to trigger rerender
            } 
        } 
    }

    return (
        <div>
            <input
                type="file"
                name="file"
                multiple
                onChange={changedHandler} />

            <div className="form-group multi-preview">
                {(preview || []).map((url, index) => (
                    <img src={url} alt="..." key={index} style={{ height: '200px', width: '200px' }} />
                ))}
            </div>

        </div>
    )
}

export default App;

Upvotes: -2

ray
ray

Reputation: 27275

Make your preview state variable an array instead of a single value and set each item preview to the corresponding index.

This probably isn't the optimal implementation, but it's the minimal modification to your code to illustrate the idea:

const [preview, setPreview] = useState([]); // empty array initially

for (var i = 0; i < files.length; i++) {
  var file = files[i];
  reader = new FileReader();
  reader.readAsDataURL(file); 

  reader.onload = event => {
    // update the array instead of replacing the entire value of preview
    preview[i] = event.target.result;
    setPreview([...preview]); // spread into a new array to trigger rerender
  }
} 

Upvotes: 2

Related Questions