In isomorphic rendered page image can be downloaded before main script.js
file. So image can be already loaded before react
register onLoad
event - never trigger this event.
script.js
constructor(props) {
super(props);
this.handleImageLoaded = this.handleImageLoaded.bind(this);
}
handleImageLoaded() {
console.log('image loaded');
}
render() {
return (
<img src='image.jpg' onLoad={this.handleImageLoaded} />
);
}
image.jpg
is bigger than script.js
In this scenario everything is working fine. Event is registered before image is finally loaded so in console is image loaded
message.
image.jpg
is smaller than script.js
This scenario you can see problem described at the beginning of post. onLoad
event is not triggered.
What can I do in order to trigger onLoad
event in scenario 2?
To detect if image is ready on render you should check complete
property on pure javascript img
object:
constructor(props) {
super(props);
this.state = { loaded: false };
this.handleImageLoaded = this.handleImageLoaded.bind(this);
this.image = React.createRef();
}
componentDidMount() {
const img = this.image.current;
if (img && img.complete) {
this.handleImageLoaded();
}
}
handleImageLoaded() {
if (!this.state.loaded) {
console.log('image loaded');
this.setState({ loaded: true });
}
}
render() {
return (
<img src='image.jpg' ref={this.image} onLoad={this.handleImageLoaded} />
);
}
You could check the complete
property on the image before applying the onload
event.
if (!img.complete) {
// add onload listener here
}