2016-07-25 67 views
5

我有高階組件在這樣的反應:刪除事件監聽器卸載陣營

export default function (InnerComponent) { 
    class InfiniteScrolling extends React.Component { 

     constructor(props){ 
      super(props); 
     } 

     componentDidMount() { 
      window.addEventListener('scroll', this.onScroll.bind(this), false); 
     } 

     componentWillUnmount() { 
      window.removeEventListener('scroll', this.onScroll.bind(this), false); 
     } 

     onScroll() { 
      if ((window.innerHeight + window.scrollY) >= (document.body.offsetHeight - 50)) { 
       const { scrollFunc } = this.props; 
       scrollFunc(); 
      } 
     } 

     render() { 
      return <InnerComponent {...this.props} />; 
     } 
    } 

    InfiniteScrolling.propTypes = { 
     scrollFunc: PropTypes.func.isRequired 
    }; 

    return InfiniteScrolling; 
} 

卸載它們通過InfiniteScrolling被包裹的組件後,他們在那裏仍然拋出錯誤,如(當時我並滾動) :

警告:setState(...):只能更新已安裝或正在安裝的零部件 。這通常意味着您在未安裝的組件上調用了setState()。這是一個沒有操作。請檢查未定義的 組件的代碼。

儘管我確實刪除了組件卸載時的scroll事件。它沒有工作。

但是,當我改變了代碼,以這樣的:

constructor(props){ 
    super(props); 
    this.onScroll = this.onScroll.bind(this); 
} 

componentDidMount() { 
    window.addEventListener('scroll', this.onScroll, false); 
} 

componentWillUnmount() { 
    window.removeEventListener('scroll', this.onScroll, false); 
} 

似乎一切都工作正常,沒有任何問題。

我覺得他們是完全一樣的東西,但第二個工作正常,而第一個正在拋出錯誤的控制檯,如前所述!

回答

20

你總是在創造新的功能

constructor(props){ 
     super(props); 
     this.onScroll = this.onScroll.bind(this); //bind function once 
    } 

    componentDidMount() { 
     window.addEventListener('scroll', this.onScroll, false); 
    } 

    componentWillUnmount() { 
     // you need to unbind the same listener that was binded. 
     window.removeEventListener('scroll', this.onScroll, false); 
    } 
+0

媽呀,這麼簡單的錯誤! 'bind'創建一個新的函數。我的錯! –