我一直在构建组件,听取整个文档的点击,并偶然发现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
组件会将click侦听器添加到文档中,App
组件负责安装和卸载Component
。
当应用了Component
挂载事件监听器以及取消挂载侦听器时,Chrome和Firefox中的所有功能都非常完美。
但是,在IE11中,当删除侦听器时,仍然会调用处理程序函数并抛出错误,因为它会尝试findDOMNode
未安装的组件。这可能不是一个突破性问题,但它仍然让我烦恼,我想知道是否有任何解决方法。
此外,注意 - 通过event.stopPropagation
停止传播不是一种选择,因为在我的应用Component
中可以通过多种方式卸载,按钮点击只是一个示例
答案 0 :(得分:0)
这似乎是IE11中的一个错误。一些选择:
1
使用window.addEventListener/window.removeEventListener
与document.addEventListener/document.removeEventListener
应该有效。
2
我已经看到其他解决方案用isMounted
包裹处理程序:
if (this.isMounted) {
const node = ReactDOM.findDOMNode(this);
}
但不推荐isMounted
并发出警告。 It is considered an antipattern
3
当前 hack 将创建您自己的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
控制台警告。