如果你可以使用 React Hooks,一个很好的方法是useEffect
,这样事件侦听器将只订阅一次,并在组件卸载时正确取消订阅。
以下示例摘自https://usehooks.com/useEventListener/:
// Hook
function useEventListener(eventName, handler, element = window){
// Create a ref that stores handler
const savedHandler = useRef();
// Update ref.current value if handler changes.
// This allows our effect below to always get latest handler ...
// ... without us needing to pass it in effect deps array ...
// ... and potentially cause effect to re-run every render.
useEffect(() => {
savedHandler.current = handler;
}, [handler]);
useEffect(
() => {
// Make sure element supports addEventListener
// On
const isSupported = element && element.addEventListener;
if (!isSupported) return;
// Create event listener that calls handler function stored in ref
const eventListener = event => savedHandler.current(event);
// Add event listener
element.addEventListener(eventName, eventListener);
// Remove event listener on cleanup
return () => {
element.removeEventListener(eventName, eventListener);
};
},
[eventName, element] // Re-run if eventName or element changes
);
};
例如,您也可以从 npm 安装它npm i @use-it/event-listener
- 请参阅此处的项目 - https://github.com/donavon/use-event-listener。
然后,要在您的组件中使用它,您只需在您的功能组件中调用它并传递事件名称和处理程序。例如,如果您想console.log
每次按下 Escape 键时:
import useEventListener from '@use-it/event-listener'
const ESCAPE_KEYS = ['27', 'Escape'];
const App = () => {
function handler({ key }) {
if (ESCAPE_KEYS.includes(String(key))) {
console.log('Escape key pressed!');
}
}
useEventListener('keydown', handler);
return <span>hello world</span>;
}