【发布时间】:2021-01-04 01:03:08
【问题描述】:
我创建了简单但有效的下拉菜单。在此示例中,菜单仅包含文本“菜单”并且没有样式。
单击“打开菜单”按钮时,应用程序显示包含菜单的div,并将 eventListener 添加到文档单击事件中。当添加 eventListener 并且用户单击文档中的任意位置时,函数会检查菜单内是否发生了单击,如果是,则不执行任何操作。如果点击在菜单之外,它会移除 eventHandler 并关闭菜单。
这种方法有问题吗?这样做的主要问题是,如果当我单击页面上的任何链接时打开菜单,我会收到这个讨厌的反应警告:
index.js:1 警告:无法对未安装的组件执行 React 状态更新。这是一个空操作,但它表明您的应用程序中存在内存泄漏。要解决此问题,请在 useEffect 清理函数中取消所有订阅和异步任务。
如果菜单打开,我添加了useEffect 清理函数来删除 eventHandler,但这没有帮助,我仍然收到相同的错误消息。
你能指出我做错了什么吗?
const DropDown = () => {
const [open, setOpen] = useState(false);
const ref = useRef<HTMLDivElement>(null);
const closeMenu = (event: MouseEvent) => {
if (event.target && event.target instanceof HTMLElement && ref.current) {
if (ref.current.contains(event.target)) return;
}
document.removeEventListener('click', closeMenu);
setOpen(false);
};
const toggleMenu = () => {
if (!open) {
document.addEventListener('click', closeMenu);
setOpen(true);
} else {
document.removeEventListener('click', closeMenu);
setOpen(false);
}
};
useEffect(() => {
return () => {
if (open) {
document.removeEventListener('click', closeMenu);
setOpen(false);
}
};
}, [closeMenu]);
return (
<>
<button onClick={toggleMenu}>open menu</button>
{open && <div ref={ref}>menu</div>}
</>
);
};
export default DropDown;
【问题讨论】:
标签: javascript reactjs typescript use-effect