8

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

5 Answers 5

17

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

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

2 Comments

Thank you mate, but i am getting an error..First time uploads looks good, try second to upload and not selecting a file ( ie on click on cancel ) Exception occurs..
@soccerway I updated the answer. you need to check for the presence of e.target.files[0]
7

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;

2 Comments

Thank you, now it uploading the file, but I can see one bug , first you upload an image, image displays successfully- this is good. Now you click on choose file again ,but decided not choose a new image and click on cancel..exception throws TypeError: Failed to execute 'createObjectURL' on 'URL': No function was found that matched the signature provided. onChangePicture C:/Project1/src/components/Register.js:10 7 | const onChangePicture = e => { 8 | console.log('picture: ', picture); > 10 | setPicture(URL.createObjectURL(e.target.files[0]));
I try to solve ur main issue, "how can I preview the image". It is clear enough by the error message what u should add to the code.
4

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;

Comments

0

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.

Comments

0

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();

Comments

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.