问题
I created a HOC to listen for clicks outside its wrapped component, so that the wrapped component can listen and react as needed.
The HOC looks like this :
const addOutsideClickListener = (WrappedComponent) => {
class wrapperComponent extends React.Component {
constructor() {
super();
this._handleClickOutside.bind(this);
}
componentDidMount() {
document.addEventListener('click', this._handleClickOutside, true);
}
componentWillUnmount() {
document.removeEventListener('click', this._handleClickOutside, true);
}
_handleClickOutside(e) {
// 'this' here refers to document ???
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;
}
Whenever I click anywhere, I get the error "Uncaught Error: Element appears to be neither ReactComponent nor DOMNode" on the _handleOutsideClick callback.
Any ideas what could be causing this ?
Update:
OK so the source of the error is that "this" inside _handleClickOutside is now referring to 'document', which is what is expected https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#The_value_of_this_within_the_handler
This looks to be an absolute mess - it seems I can either bind the event correctly but then not be able to unbind it, or I can unbind it correctly but the binding method will throw an error...
回答1:
Try using this -
constructor() {
super();
this._handleClickOutsideRef = this._handleClickOutside.bind(this);
}
componentDidMount() {
document.addEventListener('click', this._handleClickOutsideRef, true);
}
componentWillUnmount() {
document.removeEventListener('click', this._handleClickOutsideRef, true);
}
回答2:
Binding has to be done like this -
constructor() {
super();
this._handleClickOutside = this._handleClickOutside.bind(this);
}
or use arrow function for _handleClickOutside
.
_handleClickOutside = (e) => {
// 'this' here refers to document ???
const domNode = ReactDOM.findDOMNode(this);
if ((!domNode || !domNode.contains(e.target))) {
this.wrapped.handleClickOutside();
}
}
来源:https://stackoverflow.com/questions/41740360/reactjs-higher-order-component-finddomnode-not-working-correctly