2017-01-31 1 views
3

ドキュメント全体のクリックをリッスンしてコンポーネントをビルドし、IE11の問題が発生しました。IE11で削除された後にイベントリスナー関数が呼び出されました

この問題を再現するためのシンプルなコンポーネントをいくつか書きました。

class App extends React.Component { 
 
    constructor(props) { 
 
    super(props); 
 

 
    this.state = { 
 
     show: false 
 
    } 
 
    } 
 

 
    render() { 
 
    return ( 
 
     <div> 
 
     <button 
 
      onClick={() => this.setState({ 
 
       show: !this.state.show 
 
      })} 
 
     > 
 
      Toggle 
 
     </button> 
 
     
 
     <div> 
 
      {this.state.show && (
 
      <Component /> 
 
     )} 
 
     </div> 
 
     </div> 
 
    ) 
 
    } 
 
} 
 

 
class Component extends React.Component { 
 
    constructor(props) { 
 
    super(props); 
 

 
    this.handleClick = this.handleClick.bind(this); 
 
    } 
 

 
    componentDidMount() { 
 
    console.log('listener added') 
 
    document.addEventListener('click', this.handleClick) 
 
    } 
 

 
    componentWillUnmount() { 
 
    console.log('listener removed') 
 
    document.removeEventListener('click', this.handleClick) 
 
    } 
 

 
    handleClick() { 
 
    console.log('clicked!'); 
 
    const node = ReactDOM.findDOMNode(this); 
 
    } 
 

 
    render() { 
 
    return <div>Component</div> 
 
    } 
 
} 
 

 

 
ReactDOM.render(
 
    <App /> , 
 
    document.getElementById('container') 
 
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> 
 
<div id="container"></div>

ので、Componentコンポーネントは、文書化し、リスナーをクリックして追加し、App部品は取り付けとComponentをアンマウントの世話をします。

Componentがマウントされ、イベントリスナーが適用され、アンマウントされたリスナーが削除されると、ChromeとFirefoxですべて機能します。

ただし、IE11では、リスナーが削除されても、ハンドラ関数は引き続き呼び出され、アンマウントされたコンポーネントのfindDOMNodeを試してエラーがスローされます。これは大きな問題ではないかもしれませんが、まだ私にはバグがあり、回避策があるかどうかを知りたいと思います。また

、ノート - event.stopPropagation経由停止伝播私のアプリでComponentは、多くの方法でアンマウントすることができますので、ボタンのクリックは一例

JSFiddle reproducing the issue

答えて

0

あるオプションではありませんバグのようですIE11。いくつかのオプション:

1.

動作するはずwindow.addEventListener/window.removeEventListenerdocument.addEventListener/document.removeEventListenerを使用します。

​​

しかしisMountedは廃止され、警告を与える:

2.

私は他のソリューションは、isMountedでハンドラをラップ見てきました。 It is considered an antipattern。現在ハック独自01​​を作成することです

3.

。何かのように:

componentDidMount() { 
    this.mounted = true; 
    document.addEventListener('click', this.handleClick) 
} 

componentWillUnmount() { 
    this.mounted = false; 
    document.removeEventListener('click', this.handleClick) 
} 

handleClick() { 
    if (this.mounted) { 
     const node = ReactDOM.findDOMNode(this); 
    } 
} 

しかし、これはisMountedコンソール警告の周りにのみ取得します。

関連する問題