CraZyDroiD
CraZyDroiD

Reputation: 7105

How to display a image selected from input type = file in reactJS

I'm trying to display a image selected from my computer in my web app. I referred the following question which addresses the question i'm trying to fix.

How to display selected image without sending data to server?

I have my html part like this

 <div className="add_grp_image_div margin_bottom">
      <img src={img_upload} className="add_grp_image"/>
      <input type="file" className="filetype" id="group_image"/>
      <span className="small_font to_middle">Add group image</span>
      <img id="target"/>
 </div>

I want to display the selected image in

<img id="target"/>

How can i do this?

I referred FileReader docs as well.

https://developer.mozilla.org/en-US/docs/Web/API/FileReader

Upvotes: 57

Views: 91404

Answers (3)

Giang Le
Giang Le

Reputation: 7044

Hook version:

const [image, setImage] = useState(null)

const onImageChange = (event) => {
 if (event.target.files && event.target.files[0]) {
   setImage(URL.createObjectURL(event.target.files[0]));
 }
}

return (
  <div>
    <input type="file" onChange={onImageChange} className="filetype" />
    <img alt="preview image" src={image} />
  </div>
)

Class version

render() {
   return (
     <div>
       <input type="file" onChange={this.onImageChange} className="filetype" />
       <img alt="preview image" src={this.state.image}/>
     <div/>
   )
}

onImageChange = (event) => {
 if (event.target.files && event.target.files[0]) {
   this.setState({image: URL.createObjectURL(event.target.files[0])});
 }
}

Another solution is to use FileReader

onImageChange = (event) => {
  if (event.target.files && event.target.files[0]) {
    const reader = new FileReader();
    reader.onload = (e) => {
      setImage(e.target.result);
    };
    reader.readAsDataURL(event.target.files[0]);
  }
}

Working demo: https://codesandbox.io/s/priceless-cerf-my900b

Upvotes: 152

Abeid Ahmed
Abeid Ahmed

Reputation: 355

Recently I came across needing a similar feature. Here is my implementation using hooks.

export default function App() {
  const [image, setImage] = React.useState("");
  const imageRef = React.useRef(null);

  function useDisplayImage() {
    const [result, setResult] = React.useState("");

    function uploader(e) {
      const imageFile = e.target.files[0];

      const reader = new FileReader();
      reader.addEventListener("load", (e) => {
        setResult(e.target.result);
      });

      reader.readAsDataURL(imageFile);
    }

    return { result, uploader };
  }

  const { result, uploader } = useDisplayImage();

  return (
    <div className="App">
      <input
        type="file"
        onChange={(e) => {
          setImage(e.target.files[0]);
          uploader(e);
        }}
      />
      {result && <img ref={imageRef} src={result} alt="" />}
    </div>
  );
}

I created a custom hook so that it can be reused anywhere in the app. The hook returns the image src and the uploader function. The image src can then be linked to the <img src={..} /> and then on input change you can just pass in the e to the uploader function.

Upvotes: 7

Buk Lau
Buk Lau

Reputation: 1630

hope it works for you

            <form onSubmit={form => submitForm(form)}>
              <input
                accept="image/*"
                onChange={onImageChange}
                className={classes.inputImage}
                id="contained-button-file"
                multiple
                name="image"
                type="file"
              />
              <label htmlFor="contained-button-file">
                <IconButton component="span">
                  <Avatar
                    src={mydata.imagePreview}
                    style={{
                      margin: "10px",
                      width: "200px",
                      height: "200px"
                    }}
                  />
                </IconButton>
              </label>
              <Button
                type="submit"
                variant="outlined"
                className={classes.button}
              >
                Default
              </Button>
            </form>

onImageChange

  const onImageChange = event => {
    if (event.target.files && event.target.files[0]) {
      let reader = new FileReader();
      let file = event.target.files[0];
      reader.onloadend = () => {
        setData({
          ...mydata,
          imagePreview: reader.result,
          file: file
        });
      };
      reader.readAsDataURL(file);
    }
  };

submitForm

  const submitForm = form => {
    form.preventDefault();
    const formData = new FormData();
    formData.append("image", mydata.file);
    // for (var pair of formData.entries()) {
    //   console.log(pair[1]);
    // }
    const config = {
      headers: {
        "content-type": "multipart/form-data"
      }
    };
    axios
      .post("api/profile/upload", formData, config)
      .then(response => {
        alert("The file is successfully uploaded");
      })
      .catch(error => {});
  };

Upvotes: 3

Related Questions