2017-08-21 66 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.

多次 - 看起來像一次爲每個稱爲圖像。由於圖像組件仍然有效,它似乎沒有對任何事情產生嚴重影響。我想知道如何擺脫這個錯誤,但我無法弄清楚如何。

因此,這裏是我的組件:

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

所以,唯一一次的setState被稱爲是當onLoadcomponentDidUpdate被調用。我的想法是,因爲它唯一被調用的是掛載並更新它不應該得到這個錯誤。尋找任何有關如何清理這個錯誤的見解,因爲它讓我感到困惑。如果需要其他信息,我很樂意提供。

+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

我正在使用REDX我會給這個鏡頭。謝謝! – ajmajmajma

+0

我能夠通過你的線索解決這個問題,只要不裝載組件就不允許'loadImage'觸發。再次感謝。 – ajmajmajma

相關問題