soccerway
soccerway

Reputation: 11921

Preview of uploaded image in React js using React hooks

Using React hooks how can I preview the image under previewProfilePic > img area after uploading the image via choose file input.

import React, { useState } from "react";

  const Register = () => {
  const [picture, setPicture] = useState(null);

  const onChangePicture = e => {
    console.log('picture: ', picture);
    setPicture(e.target.files[0]);
};
  return (
    <div className="register_wrapper">
      <div className="register_player_column_layout_one">
        <div className="register_player_Twocolumn_layout_two">
          <form className="myForm">
            <div className="formInstructionsDiv formElement">
              <h2 className="formTitle" >Sign Up</h2>
              <p className="instructionsText"></p>
              <div className="register_profile_image">
                 <input id="profilePic" type="file" onChange={onChangePicture}/>
              </div>
              <div className="previewProfilePic" >
                <img className="playerProfilePic_home_tile"  src=""></img>
              </div>
            </div>
            <div className="fillContentDiv formElement">
              <div className="names formContentElement">
                <input className="inputRequest " type="text" placeholder="First Name" />
                <input className="inputRequest " type="text" placeholder="Last Name" />
              </div>
            </div>
            <div className="submitButtonDiv formElement">
              <button className="submitButton">Register</button>
            </div>
          </form>
        </div>
      </div>
    </div>
  );
}

export default Register;

<div className="register_profile_image">
  <input id="profilePic" type="file" onChange={onChangePicture}/>
</div>

enter image description here

Upvotes: 8

Views: 28067

Answers (5)

Lamech Desai
Lamech Desai

Reputation: 777

You can use this example below is your UploadImages.js

import React, {useState } from "react";
import PropTypes from "prop-types";
import FileUploadService from "./Services/FileUploadService";

export const UploadImages = (props) => {
  const [currentFile, setCurrentFile] = useState("");
  const [previewImage, setPreviewImage] = useState("");
  const [progress, setProgress] = useState("");
  const [message, setMessage] = useState("");
  const [imageInfos, setImageInfos] = useState("");

  const componentDidMount = () => {
    FileUploadService.getFiles().then((response) => {
      setImageInfos(response.data);
    });
  };

  const selectFile = (event) => {
    setCurrentFile(event.target.files[0]);
    setPreviewImage(event.target.files[0]);
    setProgress(0);
    setMessage("");
  };

  const upload = () => {
    setProgress(0);

    FileUploadService.upload(currentFile, (event) => {
      setProgress(Math.round((100 * event.loaded) / event.total));
    })
      .then((response) => {
        setMessage(response.data.message);
        return FileUploadService.getFiles();
      })
      .then((files) => {
        setImageInfos(files.data);
      })
      .catch((err) => {
        setProgress(0);
        setMessage("Could not upload the image!");
        setCurrentFile("undefined");
      });
  };

  return (
    <div>
      <div className="row">
        <div className="col-8">
          <label className="btn btn-default p-0">
            <input type="file" accept="image/*" onChange={selectFile} />
          </label>
        </div>

        <div className="col-4">
          <button
            className="btn btn-success btn-sm"
            disabled={currentFile}
            onClick={upload}
          >
            Upload
          </button>
        </div>
      </div>

      {currentFile && (
        <div className="progress my-3">
          <div
            className="progress-bar progress-bar-info progress-bar-striped"
            role="progressbar"
            aria-valuenow={progress}
            aria-valuemin="0"
            aria-valuemax="100"
            style={{ width: progress + "%" }}
          >
            {progress}%
          </div>
        </div>
      )}

      {previewImage && (
        <div>
          <img className="preview" src={previewImage} alt="" />
        </div>
      )}

      {message && (
        <div className="alert alert-secondary mt-3" role="alert">
          {message}
        </div>
      )}

      <div className="card mt-3">
        <div className="card-header">List of Files</div>
        <ul className="list-group list-group-flush">
          {imageInfos &&
            imageInfos.map((img, index) => (
              <li className="list-group-item" key={index}>
                <a href={img.url}>{img.name}</a>
              </li>
            ))}
        </ul>
      </div>
    </div>
  );
};

UploadImages.propTypes = {};

Here goes Your FileUpload.js file:

import http from "../Controllers/API/image-http";

class FileUploadService {
    upload(file, onUploadProgress) {
      let formData = new FormData();
  
      formData.append("file", file);
  
      return http.post("/upload", formData, {
        headers: {
          "Content-Type": "multipart/form-data",
        },
        onUploadProgress,
      });
    }
  
    getFiles() {
      return http.get("/files");
    }
  }
  
  export default new FileUploadService();

Upvotes: 0

poeticGeek
poeticGeek

Reputation: 1041

react-uploady makes this very simple. A lot less code for you to write:

a very simple example can be this:

import React from "react";
import Uploady from "@rpldy/uploady";
import UploadButton from "@rpldy/upload-button";
import UploadPreview from "@rpldy/upload-preview";

export const App = () => (
     <Uploady destination={{ url: "my-server.com/upload" }}>     
        <UploadButton/>
        <UploadPreview
            fallbackUrl="https://icon-library.net/images/image-placeholder-icon/image-placeholder-icon-6.jpg"/>
    </Uploady>
);

there's more samples in the upload-preview readme.

Upvotes: 0

Ishwar
Ishwar

Reputation: 6121

URL.createObjectURL() static method creates a DOMString containing a URL representing the object given in the parameter. The URL lifetime is tied to the document in the window on which it was created. The new object URL represents the specified File object or Blob object.

enter image description here

import React, { useState } from "react";

  const Register = () => {
  const [picture, setPicture] = useState(null);

  const onChangePicture = e => {
    setPicture(URL.createObjectURL(e.target.files[0]) );
};
  return (
    <div className="register_wrapper">
      <div className="register_player_column_layout_one">
        <div className="register_player_Twocolumn_layout_two">
          <form className="myForm">
            <div className="formInstructionsDiv formElement">
              <h2 className="formTitle" >Sign Up</h2>
              <p className="instructionsText"></p>
              <div className="register_profile_image">
                 <input id="profilePic" type="file" onChange={onChangePicture}/>
              </div>
              <div className="previewProfilePic" >
                <img className="playerProfilePic_home_tile"  src={picture && picture}></img>
              </div>
            </div>
            <div className="fillContentDiv formElement">
              <div className="names formContentElement">
                <input className="inputRequest " type="text" placeholder="First Name" />
                <input className="inputRequest " type="text" placeholder="Last Name" />
              </div>
            </div>
            <div className="submitButtonDiv formElement">
              <button className="submitButton">Register</button>
            </div>
          </form>
        </div>
      </div>
    </div>
  );
}

export default Register;

Upvotes: 4

Shubham Khatri
Shubham Khatri

Reputation: 281606

In order to see a preview you need to read the image and set the state with base64 format data that you receive and render that as source of image tag.

To read files data you can make use of FileReader

export default () => {
  const [picture, setPicture] = useState(null);
  const [imgData, setImgData] = useState(null);
  const onChangePicture = e => {
    if (e.target.files[0]) {
      console.log("picture: ", e.target.files);
      setPicture(e.target.files[0]);
      const reader = new FileReader();
      reader.addEventListener("load", () => {
        setImgData(reader.result);
      });
      reader.readAsDataURL(e.target.files[0]);
    }
  };
  return (
    <div className="register_wrapper">
      <div className="register_player_column_layout_one">
        <div className="register_player_Twocolumn_layout_two">
          <form className="myForm">
            <div className="formInstructionsDiv formElement">
              <h2 className="formTitle">Sign Up</h2>
              <p className="instructionsText" />
              <div className="register_profile_image">
                <input id="profilePic" type="file" onChange={onChangePicture} />
              </div>
              <div className="previewProfilePic">
                <img className="playerProfilePic_home_tile" src={imgData} />
              </div>
            </div>
            <div className="fillContentDiv formElement">
              <div className="names formContentElement">
                <input
                  className="inputRequest "
                  type="text"
                  placeholder="First Name"
                />
                <input
                  className="inputRequest "
                  type="text"
                  placeholder="Last Name"
                />
              </div>
            </div>
            <div className="submitButtonDiv formElement">
              <button className="submitButton">Register</button>
            </div>
          </form>
        </div>
      </div>
    </div>
  );
};

Working Demo

Upvotes: 17

user10454516
user10454516

Reputation: 1143

I have not test this yet, but, what you have to do is convert the file to URL by doing this => URL.createObjectURL(event.target.files[0]).

import React, { useState } from "react";

const Register = () => {
  const [picture, setPicture] = useState('');

  const onChangePicture = e => {
    console.log('picture: ', picture);
    setPicture(URL.createObjectURL(e.target.files[0]));
  };

  return (
    <div className="register_wrapper">
      <div className="register_player_column_layout_one">
        <div className="register_player_Twocolumn_layout_two">
          <form className="myForm">
            <div className="formInstructionsDiv formElement">
              <h2 className="formTitle" >Sign Up</h2>
              <p className="instructionsText"></p>
              <div className="register_profile_image">
                 <input id="profilePic" type="file" onChange={onChangePicture}/>
              </div>
              <div className="previewProfilePic" >
                <img className="playerProfilePic_home_tile"  src={picture}></img>
              </div>
            </div>
            <div className="fillContentDiv formElement">
              <div className="names formContentElement">
                <input className="inputRequest " type="text" placeholder="First Name" />
                <input className="inputRequest " type="text" placeholder="Last Name" />
              </div>
            </div>
            <div className="submitButtonDiv formElement">
              <button className="submitButton">Register</button>
            </div>
          </form>
        </div>
      </div>
    </div>
  );
}

export default Register;

Upvotes: 7

Related Questions