OS Hewawitharana
OS Hewawitharana

Reputation: 75

Preview and upload two separate images in the same component in react js

I have added two input fields to get profile image and cover photo in the same component. First I upload and preview cover photo. Thereafter I upload profile image. When uploading this profile image cover photo will render again. As I'm going to preview both these images, when uploading one image after the other it will disappear both images for a while and then load both together. I know that this is happened as it renders the both element when calling onChange method in uploading one image. How can I avoid this disappearing problem(rendering both elements when uploading one image)?

Here is the code.

import React, { Component } from "react";
import "./UserProfile.css";
import img from "../../assets/img/3.jpg";

class ProfileImages extends Component {
  constructor(props) {
    super(props);
    this.state = {
      isLoading: true,
      profileImage: null,
      coverImage: null,
      uploading: false
    };
  }

  handleOnChangeImage = event => {
    event.preventDefault();
    this.setState(
      {
        profileImage: event.target.files[0]
      },
      () => {
        console.log("wwwwww", this.state.profileImage);
      }
    );
  };

  handleOnChangeCoverImage = event => {
    event.preventDefault();
    this.setState({
      coverImage: event.target.files[0]
    });
  };

  render() {
      console.log("profileImage")
    return (
      <div className="animated fadeIn mt-4">
        <div
          className="card card-body responsive"
          style={{
            height: "300px",
            maxWidth: "100%",
            backgroundImage: `url(${
              this.state.coverImage != null
                ? URL.createObjectURL(this.state.coverImage)
                : "https://picsum.photos/id/863/200/200"
            })`,
            backgroundSize: "cover",
            backgroundPosition: "center",
            backgroundRepeat: "no-repeat"
          }}
        >
          <div className="row" style={{ height: "100%" }}>
            <div className="col-3 col-md-3">
              <div
                onClick={() => this.fileInput.click()}
                className="card card-body responsive profileImg"
                style={{
                  width: "100%",
                  height: "100%",
                  borderRadius: "100%",
                  backgroundImage: `url(${
                    this.state.profileImage != null
                      ? URL.createObjectURL(this.state.profileImage)
                      : img
                  })`,
                  backgroundSize: "cover",
                  backgroundPosition: "center",
                  backgroundRepeat: "no-repeat"
                }}
              >
                <div className="middle">
                  <div className="text">
                    <i className="icon-camera" />
                  </div>
                </div>
              </div>
              <input
                name="profileImg"
                type="file"
                id="profileImg"
                onChange={this.handleOnChangeImage}
                style={{ display: "none" }}
                ref={fileInput => (this.fileInput = fileInput)}
              />
            </div>
            <div className="col-8" />

            {/* cover image */}
            <div className="button col-1">
              <label htmlFor="coverImg" className="float-right">
                <i className="fa fa-camera" style={{ fontSize: "30px" }} />
              </label>
              <input
                name="coverImg"
                type="file"
                id="coverImg"
                onChange={this.handleOnChangeCoverImage}
                style={{ display: "none" }}
              />
            </div>
          </div>
        </div>
      </div>
    );
  }
}

export default ProfileImages;

Upvotes: 0

Views: 1580

Answers (1)

martink
martink

Reputation: 152

From MDN documentation:

"Each time you call window.URL.createObjectURL(), a unique object URL is created even if you've created an object URL for that file already."

This is the reason for repeated re-rendering. The already uploaded picture URL changes each time, so react re-renders it.
If you store the created URLs in the state instead of the file name, it will not re-render every time the other image changes:

handleOnChangeImage = event => {
  event.preventDefault();
  this.setState({
    profileImage: URL.createObjectURL(event.target.files[0])      

...

handleOnChangeCoverImage = event => {
  event.preventDefault();
  this.setState({
    coverImage: URL.createObjectURL(event.target.files[0])
  });
};

Upvotes: 1

Related Questions