Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cancel Image onload when component unmounts

I have a react app where I load images using another component called load-image.

Now I pass src to load-image, it shows a nice loader till image loads, and when its loaded, it shows a nice animation of image.

The problem arises here. I opened the app page, All images start loading. Now user goes to another page, the images are still loading. I can see them loading in the console. Now I get this error in console.

Warning: setState(...): Can only update a mounted or mounting component. This usually means you called setState() on an unmounted component. This is a no-op. Please check the code for the undefined component.

Here is my code.

export default class LoadImage extends React.Component {

  constructor() {
    super();
    this.state = {
      isLoaded: false,
      isMounted: false,
    };
    this.onImageLoad = this.onImageLoad.bind(this);
  }

  componentDidMount() {
    const imgSrc = this.props.imageSrc;
    const img = new window.Image();
    img.onload = this.onImageLoad;
    img.src = imgSrc;
    this.setState({
      isMounted: true,
    });
  }
  componentWillUnmount() {
    this.setState({
      isMounted: false,
    });
  }

  onImageLoad() {
    const self = this;
    if (self.state.isMounted === true) {
      self.setState({
        isLoaded: true,
      });
    }
  }
  render() {
    const self = this;
    const imageClasses = classNames({
      'image-loaded': self.state.isLoaded,
      'image': true,
    });
    const imgStyle = {
      backgroundImage: 'url("' + self.props.imageSrc + '")',
      backgroundSize: 'cover',
      backgroundPosition: 'center',
      backgroundRepeat: 'no-repeat',
      width: 'inherit',
      height: 'inherit',
    };
    return (
      <div className="image-loader">
        <div style={ imgStyle } className={ imageClasses }>
        </div>
      </div>
    );
  }
}

How can i cancel older request so that they don't update state after unmounting. I am already using state to check if component is mounted or not. Thanks.

like image 555
Ateev Chopra Avatar asked Dec 09 '15 18:12

Ateev Chopra


People also ask

What happens in component unmount?

The componentWillUnmount() method allows us to execute the React code when the component gets destroyed or unmounted from the DOM (Document Object Model). This method is called during the Unmounting phase of the React Life-cycle i.e before the component gets unmounted.

How do you check if a component is unmounting?

The useEffect() hook is called when the component is mounted and sets the mounted. current value to true . The return function from the useEffect() hook is called when the component is unmounted and sets the mounted. current value to false .

When component will unmount is called?

The componentWillUnmount method is called when the component is about to be removed from the DOM.

How do you unmount a component itself?

You can just unmount it conditionally. All you have to do is remove it from the DOM in order to unmount it. As long as renderMyComponent = true , the component will render. If you set renderMyComponent = false , it will unmount from the DOM.


1 Answers

You can change the callback while the image is still loading. In componentWillUnmount, set this.img.onload to a function that does nothing.

  componentDidMount() {
    const imgSrc = this.props.imageSrc;
    this.img = new window.Image();
    this.img.src = imgSrc;
    this.img.onload = this.onImageLoad;

  }
  componentWillUnmount() {
    if ( ! this.img ) {
        return;
    }
    this.img.onload = function(){};
    delete this.img;
  }

Source: https://github.com/Automattic/wp-calypso/blob/master/client/components/image-preloader/index.jsx

No need for isMounted() if you take this approach.

like image 154
user2827377 Avatar answered Sep 30 '22 03:09

user2827377