如何为同一个 React 组件添加多个事件监听器?

How to add multiple event listeners for the same react component?

如何以更可重用的方式在同一组件中添加多个事件侦听器?

  componentDidMount: function() {
    window.addEventListener('resize', this.handleVisible);
    window.addEventListener('scroll', this.handleVisible);
...
  },

  componentWillUnmount: function() {
    window.removeEventListener('resize', this.handleVisible);
    window.removeEventListener('scroll', this.handleVisible);
...

  },

您可以像这样创建自定义挂钩:

import { useEffect } from 'react'

export const useResizeScroll = callback => {
  useEffect(() => {
    window.addEventListener('resize scroll', callback);
    return () => window.removeEventListener('resize scroll', callback);
  }, [callback]);
};

然后像这样在你的组件中实现它:

const MyComponent = () => {
  useResizeScroll(handleVisible)

  function handleVisible() { ... }

  return (...)
}

注:

这将要求您转到组件的挂钩实现。

因此,如果您使用的是 this.state = { ... },则需要学习如何使用 React 的 useState 钩子:React useState Hook

更新:

如果你想让挂钩更灵活,比如选择你想让组件挂钩的事件监听器,那么你可以这样做:

export const useResizeScroll = (eventListener, callback) => {
  useEffect(() => {
    window.addEventListener(eventListener, callback);
    return () => window.removeEventListener(eventListener, callback);
  }, [callback]);
};

然后像这样实现它:

useResizeScroll('resize scroll', handleVisible)

更高级的用例:

您还可以通过使用 React Context 来改进您的自定义挂钩。下面是实现跟踪您的 window 宽度的挂钩的示例。

import React, { createContext, useContent, useEffect, useState } from 'react'

const ViewportContext = createContext({ width: window.innerWidth })

export const ViewportProvider = ({ children }) => {
  const [width, setWidth] = useState(window.innerWidth)

  function handleResize() {
    setWidth(window.innerWidth)
  }

  useEffect(() => {
    window.addEventListener('resize', handleResize)
    return () => window.removeEventListener('resize', handleResize)
  }, [])

  return (
    <ViewportContext.Provider value={{ width }}>
      {children}
    </ViewportContext.Provider>
  )
}

export const useViewport = () => {
  const { width } = useContext(ViewportContext)
  return { width }
}

然后你可以像这样在任何组件中使用它:

const { width } = useViewport()

这应该为您提供足够的信息来构建自定义挂钩以匹配您的用例。

这个:

window.addEventListener('resize scroll', callback); 

对我不起作用。

我不得不做 :

window.addEventListener('resize', callback);
window.addEventListener('scroll', callback);

但这行得通:

window.removeEventListener('resize scroll', handleResize)