简体   繁体   English

React,setState警告已安装/未安装的组件

[英]React, setState warning for mounted/unmounted component

I have a react component I am using to load my images progressively for my app which has been working great for me. 我有一个React组件,用于为我的应用程序逐步加载图像,这对我来说一直很好。 When I use it on a page to load images, though, I am seeing an error: 但是,当我在页面上使用它加载图像时,我看到一个错误:

warning.js:35 Warning: setState(...): Can only update a mounted or mounting component. warning.js:35警告:setState(...):只能更新已安装或正在安装的组件。 This usually means you called setState() on an unmounted component. 这通常意味着您在未安装的组件上调用了setState()。 This is a no-op. 这是无人值守。

Multiple times - looks like once for each image called. 多次-对于每个调用的图像来说,看起来就像一次。 It does not seem to be effecting anything seriously as the image components still work. 由于图像组件仍在工作,它似乎并没有严重影响任何事情。 I am wondering how to get rid of this error though, I cannot figure out how. 我想知道如何摆脱此错误,但我不知道如何解决。

So here is my component: 所以这是我的组件:

import React, { PropTypes } from 'react';

require('./progressive-image.scss');

export default class ProgressiveImage extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      loaded: false,
      image: props.smallImg
    };

    this.loadImage = this.loadImage.bind(this);
    this.onLoad = this.onLoad.bind(this);
    this.onError = this.onError.bind(this);
    this.image = undefined;
  }

  componentDidMount() {
    const { largeImg } = this.props;
    this.loadImage(largeImg);
  }

  onError(err) {
    console.warn('Error loading progressive image :', err);
  }

  onLoad() {
    this.setState({
      loaded: true,
      image: this.image.src
    });
  }

  componentDidUpdate(nextProps) {
    const { largeImg, smallImg } = nextProps;

    if (largeImg !== this.props.largeImg) {
      this.setState({ loaded: false, image: smallImg }, () => {
        this.loadImage(largeImg);
      });
    }
  }


  loadImage(src) {
    if (this.image) {
      this.image.onload = null;
      this.image.onerror = null;
    }

    const image = new Image();
    this.image = image;
    image.onload = this.onLoad;
    image.onerror = this.onError;
    image.src = src;
  }

  render() {
    const imgStyle = { 'paddingBottom': this.props.heightRatio };
    const { imgAlt, imgTitle } = this.props;

    return (
      <div className={`progressive-placeholder ${this.state.loaded ? 'loaded' : ''}`}>
        {this.state.loaded &&
          <img
            alt={imgAlt}
            className={`loaded`}
            src={this.state.image}
            title={imgTitle}
             />
        }
        <img className={`img-small ${!this.state.loaded ? 'loaded' : ''}`} src={this.state.image} alt="placeholder image for loading"/>
        <div style={imgStyle} ></div>
      </div>
    );
  }
}

ProgressiveImage.displayName = 'ProgressiveImage';

ProgressiveImage.propTypes = {
  bgColor: PropTypes.string,
  heightRatio: PropTypes.string.isRequired,
  largeImg: PropTypes.string.isRequired,
  smallImg: PropTypes.string.isRequired,
  imgAlt: PropTypes.string,
  imgTitle: PropTypes.string,
};

So the only time setState is called is when onLoad or componentDidUpdate is called. 因此,只有在调用onLoadcomponentDidUpdate时才调用setState。 My thinking is that because its only called did mount and did update it should not be getting this error. 我的想法是,因为它仅被调用完成安装和更新,所以不会出现此错误。 Looking for any insight on how to clean up this error, as it has me puzzled. 寻找有关如何清除此错误的任何见解,这让我感到困惑。 If any additional info is needed, I am happy to provide. 如果需要任何其他信息,我很乐意提供。

The problem is your callback in image.onload could be called at any random point : 问题是您可以在任意随机点调用image.onload的回调:

    image.onload = this.onLoad;

Chances are this.onLoad is being called while your component is rendering. 可能是this.onLoad在组件渲染时被调用。

The problem is that because this.onLoad is called when your external image resource loads then when you are doing this.setState , your component could be rendering and this would cause the error . 问题是,因为this.onLoad当你的外在形象资源负载那么当你正在做的是叫做this.setState ,您的组件可以被渲染, 这将导致该错误

To handle this I would recommend setting the loaded / image values outside of the local Component state and instead dispatch it to a global state using something like redux . 为了解决这个问题,我建议在本地Component状态之外设置loaded / image值,而使用redux类的方法dispatchdispatch到全局状态。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 即使组件已安装,也未安装 setState 警告 - Unmounted setState warning even though the component is mounted React - 未安装组件上的 setState() - React - setState() on unmounted component 反应警告:无法在未安装的组件上调用 setState(或 forceUpdate) - React Warning: Can't call setState (or forceUpdate) on an unmounted component 警告:无法在React Native中的已卸载组件上调用setState(或forceUpdate) - Warning: Can't call setState (or forceUpdate) on an unmounted component in React Native 如何避免警告:无法在未安装的组件上设置状态? 反应本机 - How to avoid warning: Cannot setState on unmounted component? REACT-NATIVE 反应-警告:无法在未安装的组件上调用setState(或forceUpdate) - React - Warning: Can't call setState (or forceUpdate) on an unmounted component 反应警告setState(…):只能更新已安装或正在安装的组件 - React warning setState(…): Can only update a mounted or mounting component 反应警告:setState(…)只能更新已安装或正在安装的组件 - React Warning: setState(…) Can only update a mounted or mounting component 警告:setState(…):只能更新已安装或正在安装的组件 - Warning react : setState(…): Can only update a mounted or mounting component React 多次安装和卸载相同的组件 - React Same component mounted and unmounted multiple times
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM