首页 > 解决方案 > 优化具有窗口事件监听器的组件数组

问题描述

我有一组数据,需要渲染一个具有窗口事件侦听器的相同组件的数组。但是如果我们在页面上有 20 个事件监听器,那么我们在页面上就会出现超级冻结。如何在一个相同组件的数组上设置一个事件监听器?

许多事件监听器

class BmResponsiveMenuButton extends PureComponent {
  lastWidth = 0
  resizeStep = 0
  state = {
    hidden: false
  }

  componentDidMount() {
  //HERE ADDING EVENT LISTENERS (TOTALLY WE HAVE 15-20 LISTENERS ON PAGE)
    window.addEventListener('resize', this.handleResize)
    window.addEventListener('scroll', this.handleScroll, false)
    this.anchorMenuButton = document.getElementById(this.props.moreMenuButtonId)
  }

  handleResize = () => {
    this.handleHiddenOrNot()
  }

  componentDidUpdate() {
    this.lastWidth = document.documentElement.clientWidth
  }

  handleHiddenOrNot = () => {
    this.resizeStep = Math.abs(this.lastWidth - document.documentElement.clientWidth)

    let boundingMenu = this.anchorMenuButton.getBoundingClientRect()
    let boundingButton = this.anchorEl.getBoundingClientRect()
    if (boundingButton.right > boundingMenu.left - 10) {
      this.setState({
        hidden: true
      })
      this.props.onHide(this.props.id)
    } else {
      this.setState({
        hidden: false
      })
      this.props.onUnHide(this.props.id)
    }
  }

  handleScroll = () => {
    this.handleResize()
  }

  componentWillUnmount() {
    window.removeEventListener('resize', this.handleResize)
    window.removeEventListener('scroll', this.handleScroll, false)
  }

  handleExited = () => {
    let elem = this.anchorEl
    elem.style.opacity = '0'
    elem.style.visibility = 'hidden'
  }

  handleEnter = () => {
    let elem = this.anchorEl
    elem.style.opacity = '1'
    elem.style.visibility = 'visible'
    elem.style.position = 'sticky'
  }
  render() {
    const {
      title,
      url,
      classes,
      target,
      effects,
      effectType,
      index,
      active,
      currentModule,
      module
    } = this.props
    const transitionProps = {
      key: title,
      in: !this.state.hidden,
      enter: true,
      exit: true,
      timeout: !effects ?
        0 : {
          enter: this.resizeStep > 200 ? index * 100 : 300,
          exit: 200
        },
      onEnter: () => this.handleEnter(),
      onExited: () => this.handleExited()
    }
    let activeModule
    if (module && currentModule === module) {
      activeModule = true
    } else if (active) {
      activeModule = active
    } else {
      activeModule = url.includes(window.location.pathname + window.location.search + window.location.hash)
    }
    const ButtonComponent = ( <
      Link to = {
        url
      }
      target = {
        target
      }
      innerRef = {
        (node) => (this.anchorEl = node)
      } >
      <
      Button className = {
        classNames(classes.topNavigationButton, activeModule ? classes.selected : '')
      } > {
        title
      } <
      /Button> < /
      Link >
    )
    switch (effectType) {
      case 'slide':
        return ( <
          Slide direction = {
            'left'
          } { ...transitionProps
          } > {
            ButtonComponent
          } <
          /Slide>
        )

      case 'fade':
        return <BmFade { ...transitionProps
        } > {
          ButtonComponent
        } < /BmFade>

      case 'grow':
        return <BmGrow { ...transitionProps
        } > {
          ButtonComponent
        } < /BmGrow>

      default:
        break
    }
  }
}

使用代码示例进行编辑。如果它不适合窗口,我会使用这个组件来显示或隐藏按钮。我评论我创建 eventListeners 的地方

标签: reactjsoptimizationaddeventlistenerevent-listener

解决方案


推荐阅读