我想创建一个下拉菜单,它显示自己,悬停时隐藏,单击项目后消失。我想我找到了一种方法来做这件事,但它只是有时有效。(或者它可能不起作用,但有时确实起作用。(详细信息如下:
- 我必须DropdownMenu2组件,
display
由onMouseEnter/Leave
事件切换。此组件(我的下拉菜单(包含在<NavLink>
菜单项中 - 我希望下拉菜单在点击菜单项后消失,所以在
<Navlink>
中我创建了触发handleClick
的onClick
事件。此函数将click
变量-设置为具有display:none
的CSSclassName
。CCD_ 10然后被传递到包含下拉菜单的CCD_ - 为了在鼠标悬停时再次切换下拉菜单
display
,我必须从div
中去掉click
类。为此,我创建了具有click
依赖关系的useEffect
钩子,因此每当click
状态更改时,它就会触发。这个钩子内的函数-更改click
的值,因此它不再表示CSSdisplay:none
类。因此,在(2.(-包含下拉菜单的div
具有display:none
之后,取消显示,并且useEffect
擦除该内容-使其做好悬停准备
问题:
这只在某些情况下有效——有时useEffect
在onClick
之后被触发得太快,以至于下拉菜单甚至不会下降。(click
变化如此之快,以至于div
容器在display:none
类之后立即获得"擦除"类(
NaviMainButtonDrop2
import DropdownMenu2 from "./DropdownMenu2";
import useHoverButton from "./sub-components/useHoverButton";
const NaviMainButtonDrop2 = () => {
const { disp, hoverOn, hoverOff } = useHoverButton();
return (
<li
className={`nav-main__button dropdown-us`}
>
<a
className="hover-pointer"
onMouseEnter={hoverOn}
onMouseLeave={hoverOff}
>
title
</a>
{ disp && <DropdownMenu2 /> }
</li>
)
}
export default NaviMainButtonDrop2
useHoverButton(NaviMainButtonDrop2的自定义挂钩(
import { useState } from "react";
const useHoverButton = () => {
const [disp, setDisp] = useState(false);
const hoverOn = () => setDisp(true)
const hoverOff = () => setDisp(false)
return { disp, hoverOn, hoverOff }
}
export default useHoverButton
下拉菜单2
import "./DropdownMenu.css"
import { NavLink } from "react-router-dom";
import { MenuItemContentSchool } from "./sub-components/MenuItemContentSchool"
import { useEffect } from "react";
import useAddClass from "./sub-components/useAddClass";
const DropdownMenu2 = () => {
const { click, setClick, handleClick } = useAddClass("hide-menu");
useEffect(() => {
console.log("[usEffect]")
setClick("");
}, [click]);
return (
<div className={`dropdown-holder-us ${click}`}>
{/* here menu unfolds */}
{MenuItemContentSchool.map((item) => {
return (
<NavLink
to={item.link}
className={(navData) => (navData.isActive ? "d-content-us active-style" : 'd-content-us')}
onClick={handleClick}
key={item.id}
>
{item.title}
</NavLink>
)
})}
</div>
)
}
export default DropdownMenu2
useAddClass(DropdownMenu2的自定义挂钩(
import { useState } from "react"
const useAddClass = (className) => {
const [click, setClick] = useState("");
const handleClick = () => setClick(className);
return { click , handleClick }
}
export default useAddClass
我认为这里的问题是,无论何时更新下一个状态,都无法获得最新状态,这就是为什么它有时有效,有时无效。
根据我的说法,可能有两种解决方案,要么使用setTimeout
,要么在设置状态时获取最新状态。
setTimeout
溶液-
useEffect(() => {
setTimeout(() => {
setClick("")
},2000)
- 尝试在更新下一个状态时始终获取最新状态
useEffect(() => {
console.log("[usEffect]")
setClick((clickLatest) => "");
}, [click]);
和
const handleClick = () => setClick((clickLatest) => className);
此回调将帮助useState
等待最新状态,然后进一步更新状态。
我想我刚刚找到了一个简单的解决方案。我不明白为什么useEffect
似乎在随机时序中工作,但在其中使用setTimeOut
,并延迟setClick
-的执行似乎就可以了。
useEffect(() => {
setTimeout(() => {
setClick("")
},2000)