优化具有窗口事件侦听器的组件数组

时间:2018-12-27 11:36:24

标签: reactjs optimization addeventlistener event-listener

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

Many event listeners

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的地方发表评论

0 个答案:

没有答案