组件卸载时取消映像onload

时间:2015-12-09 18:42:49

标签: javascript reactjs

我有一个反应应用程序,我使用另一个名为load-image的组件加载图像。

现在我将src传递给load-image,它显示了一个很好的加载器,直到图像加载,加载后,它会显示一个漂亮的图像动画。

问题出在这里。我打开了应用页面,所有图片都开始加载。 现在用户转到另一个页面,图像仍在加载。我可以在控制台中看到它们加载。现在我在控制台中收到此错误。

  

警告:setState(...):只能更新已安装或已安装   零件。这通常意味着您在已卸载时调用了setState()   零件。这是一个无操作。请检查未定义的代码   成分

这是我的代码。

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

如何取消旧请求,以便他们在卸载后不会更新状态。我已经使用state来检查组件是否已安装。谢谢。

2 个答案:

答案 0 :(得分:5)

您可以在图片仍在加载时更改回调。在componentWillUnmount中,将this.img.onload设置为不执行任何操作的函数。

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

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

如果采用这种方法,则不需要isMounted()。

答案 1 :(得分:1)

Don't call setState in componentWillUnmount. If the component is about to unmount, there's no point altering its state since it's about to be removed from the DOM.