Reactjs - Higher Order Component / findDOMNode not working correctly

☆樱花仙子☆ 提交于 2019-12-12 00:38:23

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!