Reactjs - 高阶组件卸载无法正常工作
Reactjs - Higher Order Component unmount not working correctly
我创建了一个 HOC 来监听其包装组件外部的点击,以便包装组件可以根据需要进行监听和反应。
HOC 看起来像这样:
const addOutsideClickListener = (WrappedComponent) => {
class wrapperComponent extends React.Component {
componentDidMount() {
console.log('*** component did MOUNT called ***');
document.addEventListener('click', this._handleClickOutside.bind(this), true);
}
componentWillUnmount() {
console.log('*** component will UNMOUNT called ***');
document.removeEventListener('click', this._handleClickOutside.bind(this), true);
}
_handleClickOutside(e) {
const domNode = ReactDOM.findDOMNode(this);
if ((!domNode || !domNode.contains(e.target))) {
this.wrapped.handleClickOutside();
}
}
render() {
return (
<WrappedComponent
ref={(wrapped) => { this.wrapped = wrapped }}
{...this.props}
/>
);
}
}
return wrapperComponent;
}
它工作正常...大部分时间。
当包装的组件被卸载时,方法 "componentWillUnmount" 被调用,但是 "removeEventListener" 继续监听事件,所以我收到错误消息
"Uncaught Error: findDOMNode was called on an unmounted component."
知道是什么原因造成的吗?
您的 removeEventListener
不工作的原因是因为您正试图删除 新 创建的函数。这同样适用于 addEventListener
。这是两个完全不同的函数,彼此之间没有任何参考。
你必须绑定你的方法 _handleClickOutside
所以 React 知道它只有一个版本。你通过在构造函数中绑定它来做到这一点
constructor() {
super();
this._handleClickOutside.bind(this);
}
或使用 ES6 箭头方法自动绑定它
_handleClickOutside = (e) => { ... }
现在你将绑定方法传递给你的事件监听器
document.addEventListener('click', this._handleClickOutside, true);
并分别移除侦听器。
将此添加到构造函数中:
this._handleClickOutside = this._handleClickOutside.bind(this)
然后这样做:
componentDidMount() {
document.addEventListener('click', this._handleClickOutside, true);
}
componentWillUnmount() {
document.removeEventListener('click', this._handleClickOutside, true);
}
我创建了一个 HOC 来监听其包装组件外部的点击,以便包装组件可以根据需要进行监听和反应。
HOC 看起来像这样:
const addOutsideClickListener = (WrappedComponent) => {
class wrapperComponent extends React.Component {
componentDidMount() {
console.log('*** component did MOUNT called ***');
document.addEventListener('click', this._handleClickOutside.bind(this), true);
}
componentWillUnmount() {
console.log('*** component will UNMOUNT called ***');
document.removeEventListener('click', this._handleClickOutside.bind(this), true);
}
_handleClickOutside(e) {
const domNode = ReactDOM.findDOMNode(this);
if ((!domNode || !domNode.contains(e.target))) {
this.wrapped.handleClickOutside();
}
}
render() {
return (
<WrappedComponent
ref={(wrapped) => { this.wrapped = wrapped }}
{...this.props}
/>
);
}
}
return wrapperComponent;
}
它工作正常...大部分时间。
当包装的组件被卸载时,方法 "componentWillUnmount" 被调用,但是 "removeEventListener" 继续监听事件,所以我收到错误消息 "Uncaught Error: findDOMNode was called on an unmounted component."
知道是什么原因造成的吗?
您的 removeEventListener
不工作的原因是因为您正试图删除 新 创建的函数。这同样适用于 addEventListener
。这是两个完全不同的函数,彼此之间没有任何参考。
你必须绑定你的方法 _handleClickOutside
所以 React 知道它只有一个版本。你通过在构造函数中绑定它来做到这一点
constructor() {
super();
this._handleClickOutside.bind(this);
}
或使用 ES6 箭头方法自动绑定它
_handleClickOutside = (e) => { ... }
现在你将绑定方法传递给你的事件监听器
document.addEventListener('click', this._handleClickOutside, true);
并分别移除侦听器。
将此添加到构造函数中:
this._handleClickOutside = this._handleClickOutside.bind(this)
然后这样做:
componentDidMount() {
document.addEventListener('click', this._handleClickOutside, true);
}
componentWillUnmount() {
document.removeEventListener('click', this._handleClickOutside, true);
}