跳到主要内容
版本:1.0

useEventListener

信息

在组件内部设置和清理事件监听器。

1.实现

import { useEffect, useRef } from "react";

const useEventListener = (
eventType = "",
listener = () => null,
target = null,
options = null
) => {
const savedListener = useRef();

useEffect(() => {
savedListener.current = listener;
}, [listener]);

useEffect(() => {
if (!target?.addEventListener) return;

const eventListener = (event) => savedListener.current(event);

target.addEventListener(eventType, eventListener, options);

return () => {
target.removeEventListener(eventType, eventListener, options);
};
}, [eventType, target, options]);
};

export default useEventListener;

2.使用

不需要从此 Hook 返回任何内容,因为我们只是侦听事件并运行处理程序函数传入作为参数。

现在,很容易将事件侦听器添加到我们的组件(例如以下组件)中,以检测 DOM 元素外部的点击。 如果用户单击对话框组件,则在此处关闭对话框组件。

import { useRef } from "react";
import ReactDOM from "react-dom";
import { useEventListener } from "./hooks";

const Dialog = ({ show = false, onClose = () => null }) => {
const dialogRef = useRef();

// Event listener to close dialog on click outside element
useEventListener(
"mousedown",
(event) => {
if (event.defaultPrevented) {
return; // Do nothing if the event was already processed
}
if (dialogRef.current && !dialogRef.current.contains(event.target)) {
console.log("Click outside detected -> closing dialog...");
onClose();
}
},
window
);

return show
? ReactDOM.createPortal(
<div className="fixed inset-0 z-9999 flex items-center justify-center p-4 md:p-12 bg-blurred">
<div
className="relative bg-white rounded-md shadow-card max-h-full max-w-screen-sm w-full animate-zoom-in px-6 py-20"
ref={dialogRef}
>
<p className="text-center font-semibold text-4xl">
What's up{" "}
<span className="text-white bg-red-500 py-1 px-3 rounded-md mr-1">
YouTube
</span>
?
</p>
</div>
</div>,
document.body
)
: null;
};

export default Dialog;