2017-08-21 6 views
0

私は私のために偉大な働きをしてくれた自分のイメージを徐々にイメージをロードするために使用している反応コンポーネントがあります。画像を読み込むためにページで使用すると、エラーが表示されます。マウントされた/取り付けられていないコンポーネントに対する反応、setState警告

warning.js:35 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.

複数回 - 呼び出される画像ごとに1回のように見えます。イメージコンポーネントがまだ機能しているため、真剣に何かを実行しているようには見えません。私はどのようにこのエラーを取り除くために、私はどのように把握することはできませんかと思います。だからここ

は私のコンポーネントです:

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

onLoadまたはcomponentDidUpdateが呼び出されたときにSETSTATEが呼び出されたときだけです。私の考えは、その唯一の呼び出されたがマウントし、更新を行ったので、このエラーが発生してはならないはずです。このエラーを解決する方法についての洞察を探してください。私は困惑しています。追加の情報が必要な場合は、私は提供しています。

+1

didUpdateで状態を変更することはできません。そうしないと、無限ループに入ります。 –

+0

この 'componentDidlUpdate'の入力ミスはどうでしたか? –

+0

@DimitarChristoffはそれで問題を引き起こしているのでしょうか?私はcomponentWillUpdateにそれを交換しようとしたが、まだエラーが表示されます。 – ajmajmajma

答えて

1

問題がimage.onloadであなたのコールバックは任意のランダム点で呼び出すことができます:

image.onload = this.onLoad; 

コンポーネントをレンダリングしている間、チャンスはthis.onLoad呼び出されています。

問題がthis.onLoadが呼び出されるので、あなたがthis.setStateをしているときに、外部の画像リソースの負荷が、その後、あなたのコンポーネントは、これはエラーを引き起こすレンダリングとすることができたときにということです。これを処理する

私はreduxのようなものを使用してグローバルな状態にそれをローカルComponent状態の外loaded/image値を設定し、代わりにdispatchをお勧めします。

+0

私はreduxを使用しています。私はこれを撃つでしょう。ありがとう! – ajmajmajma

+0

コンポーネントがマウントされていない場合、 'loadImage'を起動できないようにすることで、私はあなたの手がかりでこれを解決できました。再度、感謝します。 – ajmajmajma

関連する問題

 関連する問題