反应未安装的组件

时间:2018-09-26 11:34:11

标签: javascript reactjs react-16

我最近升级到了React v 16.5,并且遇到了一些组件问题。我在下面显示了其中一个在16.4.1之前可以使用的功能。这是一个简单的下载图标,当状态isOpen为true时将显示一个下拉菜单,如果您在其外部单击,将关闭其下拉菜单。

我一直收到

  

无法在尚未安装的组件上调用setState。这是一项禁止操作的操作,但可能表明您的应用程序中存在错误。而是直接分配给this.state或在DownloadIcon组件中定义具有所需状态的state = {};类属性。

堆栈跟踪指向this.setState({ isOpen: false })中的this.handleOutsideClick。我很困惑,因为我虽然挂载了isMounted(我刚刚出于调试目的而添加)的日志,但实际上并没有将其设置为true。

class DownloadIcon extends React.Component {


static propTypes = {
    chartPanelEl: PropTypes.any,
    metricId: PropTypes.string,
    datasets: PropTypes.array,
    downloadFormats: PropTypes.array,
    metadata: PropTypes.any,
    tableHeaders: PropTypes.array,
    segments: PropTypes.array
  };

  state = {
    isOpen: false,
    isMounted: false // for debugging purposes
  };

  dom = React.createRef();

  componentDidMount() {
    console.log("I MOUNT"); // logs
    this.setState({ isMounted: true });
    window.addEventListener("click", this.handleOutsideClick, true);
  }

  componentWillUnmount() {
    window.removeEventListener("click", this.handleOutsideClick, true);
  }

  /**
   * Click listener to determine state of dropdown
   * @param {Object} e - event object
   */
  handleOutsideClick = e => {
    const target = e.target;
    const validTargets = [this.dom.current].concat(
      ...this.dom.current.children
    );

    if (this.dom && this.dom.current && validTargets.includes(target)) {
      return;
    }

    this.setState({
      isOpen: false
    });
  };

  /**
   * Handle click of download icon container to set open state
   * @param {Object} e - event object
   */
  handleClick = e => {
    this.setState({ isOpen: !this.state.isOpen });
  };

  render() {
    const dropdownClassNames = "dropdown " + (this.state.isOpen ? "open" : "");

    return (
      <div
        className="download-icon__container"
        onClick={this.handleClick}
        ref={this.dom}
      >
        <img className="download-icon" src={downloadIcon} />
        <div className={dropdownClassNames}>
          <div
            id="drop"
            data-toggle="dropdown"
            role="button"
            aria-haspopup="true"
            aria-expanded="false"
            href="#"
          />
          <ul id="menu1" className="dropdown-menu" aria-labelledby="drop">
            <li className="dropdown-title">Download as</li>
            {this.renderDownloadOptions()}
          </ul>
        </div>
      </div>
    );
  }

当我现在单击下载图标时,控制台将引发警告,并且无法呈现下拉菜单。任何帮助将不胜感激,为什么这个警告不断出现以及为什么它可能会破坏功能!

0 个答案:

没有答案