Image onLoad event in isomorphic/universal react - register event after image is loaded

Everettss picture Everettss · Sep 29, 2016 · Viewed 23.5k times · Source

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} />
    );
}

Scenario 1 - image.jpg is bigger than script.js

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.


Scenario 2 - image.jpg is smaller than script.js

image.jpg is smaller than script.js

This scenario you can see problem described at the beginning of post. onLoad event is not triggered.


Question

What can I do in order to trigger onLoad event in scenario 2?


EDIT: Soviut answer implementation

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} />
    );
}

Answer

Soviut picture Soviut · Sep 29, 2016

You could check the complete property on the image before applying the onload event.

if (!img.complete) {
    // add onload listener here
}