Pomax / react-onclickoutside

An onClickOutside wrapper for React components

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

TypeError: Cannot read property 'getInstance' of null after hot reload

bockc opened this issue · comments

Hello,
I have an issue with this package. It works flawlessly until I make changes to my code which triggers a hot reload. After the hot reload, any click anywhere in the window will trigger this exception and it's becoming immensely annoying. I'm using version 6.9.0 and my wrappers are written following the ES6 Class style

How is it possible my handlers and my wrappers are working fine until I hot reload ?

I finally figured out where the problem came from.
My handlers were declared and used this way before updating React:

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import onClickOutside from 'react-onclickoutside';

class NavButton extends Component {
  static propTypes = {
    children: PropTypes.node.isRequired,
    buttonClassName: PropTypes.string,
    buttonName: PropTypes.string,
    onClick: PropTypes.func
  };

  static defaultProps = {
    onClick: () => null,
    buttonClassName: '',
    buttonName: undefined
  };

  constructor(props) {
    super(props);
    this.state = {};
  }

  handleClickOutside(evt) {
    if (this.state.active && evt.path) {
      this.setState(prevState => ({ active: !prevState.active }));
    }
  }

  render() {
    return (
      <li className="sidebar-group-item" name={this.props.buttonName}>
        <button
          className={`${this.props.buttonClassName} ${this.state.active ? 'active' : ''}`}
          onClick={() => {
            this.setState(prevState => ({ active: !prevState.active }));
            this.props.onClick();
          }}
        >
          {this.props.children}
        </button>
      </li>
    );
  }
}

export default onClickOutside(NavButton);

This way, the handlers stopped working after a hot reload, forcing me to refresh the page anyway.

I fixed it by rewriting them a little bit:

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import onClickOutside from 'react-onclickoutside';

class NavButton extends Component {
  static propTypes = {
    children: PropTypes.node.isRequired,
    buttonClassName: PropTypes.string,
    buttonName: PropTypes.string,
    onClick: PropTypes.func,
  };

  static defaultProps = {
    onClick: () => null,
    buttonClassName: '',
    buttonName: undefined,
  };

  constructor(props) {
    super(props);
    this.state = {};
  }

  handleClickOutside = (evt) => {
    if (this.state.active && evt.path) {
      this.setState((prevState) => ({ active: !prevState.active }));
    }
  };

  render() {
    return (
      <li className="sidebar-group-item" name={this.props.buttonName}>
        <button
          className={`${this.props.buttonClassName} ${this.state.active ? 'active' : ''}`}
          onClick={() => {
            this.setState((prevState) => ({ active: !prevState.active }));
            this.props.onClick();
          }}
        >
          {this.props.children}
        </button>
      </li>
    );
  }
}

const clickOutsideConfig = {
  handleClickOutside(instance) {
    return instance.handleClickOutside;
  },
};

export default onClickOutside(NavButton, clickOutsideConfig);

And now there's no more exception complaining they couldn't access the instance of my components. I don't really know if updating React alone caused this issue, but it looks like hot-reloading your app may break those handlers if not configured to use a config.

Sorry for the issue, I'm going to close it now. Thanks again for your great work :)