【问题标题】:Cancel Image onload when component unmounts卸载组件时取消图像加载
【发布时间】:2015-12-09 18:42:49
【问题描述】:

我有一个 react 应用程序,我在其中使用另一个名为 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>
    );
  }
}

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

【问题讨论】:

标签: javascript reactjs


【解决方案1】:

您可以在图像仍在加载时更改回调。在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()。

【讨论】:

    【解决方案2】:

    不要在componentWillUnmount 中调用setState。如果组件即将卸载,则没有必要更改其状态,因为它即将从 DOM 中删除。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-11-11
      • 1970-01-01
      • 2019-03-09
      • 2012-12-11
      • 1970-01-01
      • 2016-07-07
      • 2017-06-25
      • 2011-07-13
      相关资源
      最近更新 更多