Image onLoad event in isomorphic / universal response - logs an event after loading an image

In an isomorphic page rendering, the image can be downloaded before the main script.js file. Thus, the image may already be loaded before the react register of the react event - do not 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 bigger than script.js

image.jpg is bigger than script.js

In this scenario, everything is working fine. The event is logged before the image is finally loaded, so the image loaded message is in the image loaded console.


Scenario 2 - image.jpg smaller than script.js

image.jpg is smaller than script.js

In this scenario, you can see the problem described at the beginning of the post. The onLoad event is not raised.


Question

What can I do to trigger the onLoad event in script 2 ?


EDIT: Pull implementation response

To determine if an image is ready when rendering, you should check the complete property on a clean img javascript 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} /> ); } 
+12
javascript reactjs isomorphic-javascript
source share
4 answers

You can check the complete property on the image before applying the onload .

 if (!img.complete) { // add onload listener here } 
+12
source share

Another way is to use ref and cover both of these scenarios:

 <img ref={(input) => { // onLoad replacement for SSR if (!input) { return; } const img = input; const updateFunc = () => { this.setState({ loaded: true }); }; img.onload = updateFunc; if (img.complete) { updateFunc(); } }} src={imgSrc} alt={imgAlt} /> 
+2
source share

img.complete is true even if src download fails.

complete - returns a boolean value that is true if the browser has completed the selection of the image, regardless of whether it is successful or not . It also shows true if the image is not src.

  1. Use naturalWidth as the determining if the IMG download was successful or not

    state = {isLoading: true, hasError: false,}

    myRef = React.createRef ();

    componentDidMount () {const img = this.myRef.current;

     if (img && img.complete) { if (img.naturalWidth === 0) { this.handleOnError(); } else { this.handleImageLoaded(); } } 
     if (img && img.complete) { if (img.naturalWidth === 0) { this.handleOnError(); } else { this.handleImageLoaded(); } } 

    handleImageLoaded = () => {if (this.state.isLoading) {this.setState ({isLoading: false}); }}

    handleOnError = () => {this.setState ({hasError: true}); }

    render() {return(); }

+1
source share
 <img src={this.props.imageUrl} onLoad={this.handleImageLoaded.bind(this)} onError={this.handleImageErrored.bind(this)} /> 
-one
source share

All Articles