如何为同一个 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)
如何以更可重用的方式在同一组件中添加多个事件侦听器?
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)