Reputation: 75
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
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