2016-02-11 9 views
21

を更新することができ、私は次の警告はSETSTATEのみを搭載したり、部品実装

「警告取得していますリアクト()は、アンマウントされたコンポーネント上にあります。これはノーオペレーションです。ContactPageコンポーネントのコードを確認してください。

私が最初に連絡先ページに行ったとき、それは良いです。それから私がページから離れて戻ると、警告がスローされます。

Contactページコンポーネント:

import React, { Component, PropTypes } from 'react'; 
import AppStore from '../../stores/AppStore'; 
import AppActions from '../../actions/AppActions'; 
import DataContent from './DataContent'; 

const title = 'Contact Us'; 


class ContactPage extends Component { 

    constructor(props) { 
     super(props); 
     this.state = AppStore.getState(); 
     AppActions.getData(); 
    } 

    static contextTypes = { 
    onSetTitle: PropTypes.func.isRequired, 
    }; 

    componentWillMount() { 
    this.context.onSetTitle(title); 
    AppStore.listen(this.onChange.bind(this)); 
} 

componentWillUnmount() { 
    AppStore.unlisten(this.onChange.bind(this)); 
} 

onChange(state) { 
    this.setState(state); 
} 

renderData() { 
    return this.state.data.map((data) => { 
     return (
      <DataContent key={data.id} data={data} /> 
     ) 
    }) 
} 

    render() { 
    return (
     <div className={s.root}> 
     <div className={s.container}> 
      <h1>{title}</h1> 
      <div> 
       { this.renderData() } 
      </div> 
     </div> 
     </div> 
    ); 
} 

} 

export default ContactPage; 

私はデバッガを入れて、お問い合わせページの読み込み時に、それはcomponentWillMountに当たります()。連絡先ページを終了すると、componentWillUnmount()にヒットします。ページに戻ると、再びcomponentWillMount()にヒットし、onChange(state)関数にヒットしたときにエラーをスローします。

答えて

36

問題は、前のコンポーネントインスタンスのリスナーがまだ登録されていることです。前のインスタンスがもうマウントされていないため、そのエラーが発生します。

.bindは、常にという新しい関数を返します。あなたは

AppStore.unlisten(this.onChange.bind(this)); 

を行うのであれば、あなたは(もちろん失敗)が存在しないリスナーを削除しようとしています。

this.onChange = this.onChange.bind(this); 

をし、その後AppStore.listen(this.onChange)AppStore.unlisten(this.onChange)を使用します。それはあなたがこの問題を解決するにはAppStore.listen(this.onChange.bind(this))


に登録されたリスナーを削除し、あなたは、コンストラクタで一度ハンドラをバインドする必要がありないを行います。

+0

うまくいった!ありがとう:) – erichardson30

+3

"。バインドは常に新しい機能を返します" ....気が吹き! – CambridgeMike

+0

ありがとう。カップルの時間のためにそれと苦労してきた。 – Avdept

6

変更する前に、状態チェックコンポーネントがマウントされています。

render() { 
    return (
    <div ref="root" className={s.root}> 
     // ---- 
    </div> 
    )}; 

onChange(state) { 
    if(this.refs.root) { 
    this.setState(state); 
    } 
} 

これはあなたに役立つと思います。

0

あなたの場合は、ルートdivにrefを追加し、setStateを呼び出す前にref値をチェックしてください。

onChange(state) { 
    this.refs.yourRef ? this.setState(state) : null;  
} 
-1

私はかなりしばらくの間だけでなく、この問題に苦しんでいた:

あなたonChange方法は次のようになります必要があります。

私が解決したのは、@Felix Klingの提案通りでしたが、私のコールバック関数がコンポーネントのクラス内で宣言されていることを確認しました。そうでなければ、thisプレフィックスを使用できませんでした。私。

法律が、

class MyComponent extends React.Component { 
    constructor(props) { 
    super(props); 
    this.onChange = this.onChange.bind(this); 
    } 

    onChange() { 
    this.setState({ MyState: newState }) 
    } 

    componentDidMount() { 
    window.addEventListener('resize', this.onChange); 
    } 

    componentWillUnmount() { 
    window.removeEventListener('resize', this.onChange); 
    } 

    render() { ... } 
} 

はそれが役に立てば幸い

function onChange() { 
    this.setState({ MyState: newState }) 
} 

class MyComponent extends React.Component { 
    constructor(props) { 
    super(props); 
    onChange = onChange.bind(this); 
    } 

    componentDidMount() { 
    window.addEventListener('resize', onChange); 
    } 

    componentWillUnmount() { 
    window.removeEventListener('resize', onChange); 
    } 

    render() { ... } 
} 

ワークス動作しません。ここで

は、私が何を意味するかの例です。誰かeこの問題に直面している。 :)

関連する問題