Search code examples
javascriptreactjsfluxredux

Synchronize the onLoad of multiple images with React


Let's say I have an unspecified number of images that are using Andrew Farmer's example image component which detects when each individual image has loaded:

import React from 'react';

class ImageWithStatusText extends React.Component {
  constructor(props) {
    super(props);
    this.state = { imageStatus: null };
  }

  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;

Using a framework like Flux or Redux, what's the easiest way to synchronize all of the image components to detect when all images are done loading?


Solution

  • It might make sense to have counters in redux. For each image you could dispatch an action to increment a imagesOnPage counter in componentDidMount, and then dispatch an action to increment loadedImagesOnPage in handleImageMounted. And for handleImageErrored you could decrement imagesOnPage. When imagesOnPage === loadedImagesOnPage, all images are loaded.

    A more robust approach would be to generate a unique ID for each image, and have an images reducer with each key being the unique ID and the value being its status: { image_1234: 'loading', image_111: 'loaded', image_12: 'error' } You could write some utilities to look through that reducer and see if all images are in the loaded state.