当我们在 React 中实现下拉菜单或抽屉组件时,这些组件通常需要在单击菜单按钮或组件外部时关闭。
为了在我们的自定义组件中允许这种行为,我们可以创建一个自定义钩子,每当需要时,它可以应用相同的行为。
这里是一个简单的自定义钩子,它检查鼠标单击是否在当前组件的外部。
代码语言:javascript复制const useCheckOutside =
(clickOutside: () => void, exceptId?: string) => ...
我们将这个钩子命名为 useCheckOutside,它接收 clickOutside 函数作为一个属性,允许父组件接收事件。
exceptId 是一个可选属性,可用于在点击处不希望关闭行为时忽略它。我们需要这个属性,因为通常菜单或下拉按钮也是外部点击的一部分,按钮的 onClick 事件将使菜单或下拉框的可见性变为可见,而外部点击将可见性变为隐藏。下面的函数描述了 exceptId 将在 mousedown 事件中被忽略。
代码语言:javascript复制const checkOutsideClick = (event: any) => {
if (
ref.current &&
!ref.current.contains(event.target) &&
event.target.id !== exceptId
) {
clickOutside();
}
};
document.addEventListener('mousedown', checkOutsideClick);
以下是 useCheckOutside 钩子的完整代码,以及如何使用的简单示例。
代码语言:javascript复制import { useEffect, useRef } from 'react';
const useCheckOutside =
(clickOutside: () => void,
exceptId?: string) => {
const ref = useRef<any>();
useEffect(() => {
const checkOutsideClick = (event: any) => {
if (
ref.current &&
!ref.current.contains(event.target) &&
event.target.id !== exceptId
) {
clickOutside();
}
};
document.addEventListener('mousedown', checkOutsideClick);
return () => {
document.removeEventListener('mousedown', checkOutsideClick);
};
}, [clickOutside]);
return ref;
};
export default useCheckOutside;
const handleOutsideClick = () => {
setOpen(false);
}
const ref = useCheckOutside(handleOutsideClick, "buttonId");
return <>
<button id="buttonId" type="button"
onClick={(e) => {
setOpen(true)
}
>
Menu
</button>
{open && <Menu ref={ref} />}
</>
我正在参与2023腾讯技术创作特训营第三期有奖征文,组队打卡瓜分大奖!