2016-10-20 12 views
0

私は自分のコンポーネントの1つでウィンドウの「スクロール」イベントを待ち受けます。ただし、コンポーネントがでアンマウントされている場合は、、スクロールイベントリスナーは削除されていません。Reactコンポーネントでイベントリスナーをアンマウントする

コンポーネントがアンマウントされた後に、スクロールイベントが発生したとき、次のエラーが生成される:

warning.js:36警告:SETSTATE(...)のみマウントまたは 実装部品を更新することができます。これは、通常、アンマウントされたコンポーネント でsetState()を呼び出したことを意味します。これはノーオペレーションです。 TopNavDesktopコンポーネント のコードを確認してください。

このイベントリスナーを正しく削除するにはどうすればよいですか?

例コード:

class NavBar extends Component { 
    constructor() { 
    super(); 

    this.state = { 
     distanceScrolled: null 
    } 
    } 

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

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

    handleScroll(e){ 
    const distanceScrolled = e.srcElement.body.scrollTop; 

    this.setState({ distanceScrolled: distanceScrolled }); 
    } 

    render { ... } 
} 

答えて

6

リスナーを削除すると、新しい関数参照が作成されます。

someFn.bind(this) === someFn.bind(this)はfalseと評価されます。代わりに

、あなたのコンストラクタで機能を保存し、その参照を使用します。

class NavBar extends Component { 
    constructor() { 
    super(); 

    this.state = { 
     distanceScrolled: null 
    } 

    this.scrollFn = this.handleScroll.bind(this); 
    } 

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

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

    handleScroll(e){ 
    const distanceScrolled = e.srcElement.body.scrollTop; 

    this.setState({ distanceScrolled: distanceScrolled }); 
    } 

    render { ... } 
} 
+0

うわー、私は 'someFn.bind(これは)'新しい参照を作成していたことを認識していなかった驚いて。これを指摘してくれてありがとう:) –

2

あなたはこの方法でこれを実行する必要があります。

componentDidMount() { 
    this.listener = this.handleScroll.bind(this); 
    window.addEventListener('scroll', this.listener); 
} 

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

this.handleScroll.bind(this)componentWillUnmountに新しい機能を作成する代わりに、以前の通過する第2の時間を呼び出すことによって。

関連する問題