javascript - 太多的事件处理程序会影响 React 应用程序的性能吗?

标签 javascript reactjs performance web-frontend

我有一个 Toggler button 可以打开下拉菜单。要添加一项功能,如果用户单击该菜单以外的屏幕上的任何地方,下拉菜单应该关闭。因此,为此,我需要创建点击处理程序并保留发生点击的节点的记录。如果点击来自下拉节点之外,菜单应该关闭。这是代码:

  state = {
    menuTogglerOpen: false
  }

  componentWillMount() {
    document.addEventListener("mousedown", this.handleClick, false)
  }
  componentWillUnmount() {
    document.removeEventListener("mousedown", this.handleClick, false)
  }

  handleClick = event => {
    if (this.togglerNode.contains(event.target)) {
      return
    }
    this.closeMenuTogglerFromOutside()
  }

  closeMenuTogglerFromOutside = () => {
    this.setState({
      menuTogglerOpen: false
    })
  }

  handleMenuToggler = () => {
    this.setState({
      menuTogglerOpen: !this.state.menuTogglerOpen
    })
  }

JSX

<Toggler ref={currentNode=> (this.togglerNode = currentNode)}>
  <button onClick={this.handleMenuToggler}>
                <svg
                  ...button SVG...
                </svg>
              </button>
  {this.state.menuTogglerOpen && (
  <TogglerDropDown>
    <div className="_dropdown_caret" />
    <div className="_dropdown">
      <ul>
        <li>puspender</li>
        <li>settings</li>
        <li>help</li>
        <li>logout</li>
      </ul>
    </div>
  </TogglerDropDown>
  )}
</Toggler>
</HeaderGroup>
</SiteHeaderRight>   

在这种方法中,每次点击(屏幕上的任何地方)都会调用 handleClick 方法。它会影响应用程序性能吗?如果是,处理此类事件的更好方法是什么?

更新
正如 Alexei 所建议的,这是我实现的解决方案:

handleClick = event => {
    if (this.togglerNode.contains(event.target)) {
      return
    }
    this.closeMenuToggler()
  }

  openMenuToggler = () => {
    document.addEventListener("mousedown", this.handleClick, false)
    this.setState({
      menuTogglerOpen: true
    })
  }

  closeMenuToggler = () => {
    document.removeEventListener("mousedown", this.handleClick, false)
    this.setState({
      menuTogglerOpen: false
    })
  }

  handleMenuToggler = () => {
    if (this.state.menuTogglerOpen) {
      this.closeMenuToggler()
    } else {
      this.openMenuToggler()
    }
  }

最佳答案

评论:

You could attach the event listener when the menu opens, and remove it when the menu closes. Traditionally that's how most modals are implemented. Only when the modal is open do you want to listen for the click-to-close event.

这可能适用于也可能不适用于您的代码库,但您可能还想考虑删除 componentWillUnmount 上的事件监听器,这样可以避免任何潜在的内存泄漏。这涵盖了组件卸载而不调用 closeMenuToggler 的情况,在这种情况下,您将让陈旧的事件监听器继续运行。

componentWillUnMount() {
  if (this.state.menuTogglerOpen) {
    document.removeEventListener("mousedown", this.handleClick, false)
  }
}

handleClick = event => {
  if (this.togglerNode.contains(event.target)) {
    return
  }
  this.closeMenuToggler()
}

openMenuToggler = () => {
  document.addEventListener("mousedown", this.handleClick, false)
  this.setState({
    menuTogglerOpen: true
  })
}

closeMenuToggler = () => {
  document.removeEventListener("mousedown", this.handleClick, false)
  this.setState({
    menuTogglerOpen: false
  })
}

handleMenuToggler = () => {
  if (this.state.menuTogglerOpen) {
    this.closeMenuToggler()
  } else {
    this.openMenuToggler()
  }
}

关于javascript - 太多的事件处理程序会影响 React 应用程序的性能吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52902213/

相关文章:

android - 重复使用膨胀的 View ,不膨胀超过一次

c - 如何使用 C 缓冲低延迟输入并将其写入磁盘

javascript - 数据表上的 daterangepicker 插件。无法排序和搜索

javascript - 使用 typescript react redux 设置 reducer

reactjs - mapStateToProps 函数,定位帖子的 id 而不是所有帖子

reactjs - React Router - 渲染组件的问题。白屏

c - 优化此代码,使其代码运行时间小于 1s

javascript - 如何以 Rails 方式处理 JavaScript 事件(例如 'link_to :remote' )?

javascript - 只是尝试访问 a 元素中的值

javascript - 有没有办法避免在 Apache Wicket 中转义 javascript 标签?