2017-01-31 147 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的照顾。

当Chrome浏览器和Firefox启用了Component时,应用了事件侦听器,并且卸载了侦听器时,所有工作都很完美。

然而,在IE11中,当侦听器被移除时,处理函数仍然被调用并且抛出错误,因为它试图对未挂载的组件进行findDOMNode。这可能不是一个突破性的问题,但它仍然让我感到困惑,我想知道是否有任何解决方法。

此外,请注意 - 通过event.stopPropagation停止传播是不是因为我的应用程序Component可以卸下,使用方法很多选项,点击按钮仅仅是一个例子

JSFiddle reproducing the issue

回答

0

这似乎是一个错误IE11。有几个选项:

1.

使用window.addEventListener/window.removeEventListenerdocument.addEventListener/document.removeEventListener应该工作。

2.

我见过其他的解决方案包的处理程序与isMounted

​​

isMounted已被弃用,并给出警告。 It is considered an antipattern

3.

电流破解将创建自己的isMounted。例如:

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控制台警告。