Detect when images have finished loading with React


November 02, 2015

I was asked this question recently:

"Is there a way to detect when the children of a component have rendered completely?"

And the answer is, of course, componentDidMount(). componentDidMount() is called when your React component is rendered.

If you aren't familiar with componentDidMount(), go read the React Component Lifecycle Methods documentation. Each method listed there is one you will likely use eventually.

After a bit more digging, I realized that the question-asker really wanted to know when the images had finished loading. Just because React has rendered an <img> tag, that doesn't mean that the image is loaded.

Let's set up some basic definitions to distinguish rendered from loaded:

rendered: React has converted your virtual DOM elements (specified in the render method) into real DOM elements and attached them to the DOM.
loaded: Image data or other remote content has downloaded completely (or failed to download).

In case it's not clear yet, render is always before load.

Why wait for an image to load?

Weeeellll maybe when your images are done loading you want to:

  • ...hide a spinner.
  • ...automatically load more images.
  • ...reveal a UI that needs the images to make sense.
  • ...other reasons!

Read on to find out how to detect image load events.

onLoad & onError

onload and onerror are properties that have been available on the DOM <img> tag (HTMLImageElement) for quite some time. React uses camelCase for its event handlers, so these become onLoad and onError in React. They are mentioned, but not discussed, in the react documentation under Image Events.

So just add the onLoad and onErrorevent handlers to your React <img> tag and away you go. If it's still not crystal clear, read on for a code sample!

Short Example

Here's a short example of using the onLoad event handler. For a longer example that shows how to show a spinner until all your images have finished loading, see my next article: React Image Gallery.

This component, ImageWithStatusText, loads an image and displays text when finished: either 'loaded' or 'failed to load'.

import React from 'react';
 
class ImageWithStatusText extends React.Component {
  constructor(props) {
    super(props);
    this.state = { imageStatus: 'loading' };
  }
 
  handleImageLoaded() {
    this.setState({ imageStatus: 'loaded' });
  }
 
  handleImageErrored() {
    this.setState({ imageStatus: 'failed to load' });
  }
 
  render() {
    return (
      <div>
        <img
          src={this.props.imageUrl}
          onLoad={this.handleImageLoaded.bind(this)}
          onError={this.handleImageErrored.bind(this)}
          />
        {this.state.imageStatus}
      </div>
    );
  }
}
export default ImageWithStatusText;

It's pretty short, so I'll leave it to you to review the code. If you have any questions let me know in the comments!

Wasn't That Easy?

Now that you know how to use onLoad and onError why not checkout my React Image Gallery Tutorial? You'll learn how to create a React image gallery component from scratch in just 70 lines.

And if you've just learned something - why not sign up for the mailing list below? I'll ONLY send out useful articles like this one that help you learn React. Trust me - I hate spam too.

ABOUT THE AUTHOR

Andrew H Farmer
Hey, I'm Andrew. Welcome to my blog on Modern JavaScript with React. I'm constantly searching the web to stay up-to-date on the latest frontend web tools so you don't have to. Got a question? Tweet me @ahfarmer!