onClick事件后触发的useEffect-结果不同



我想创建一个下拉菜单,它显示自己,悬停时隐藏,单击项目后消失。我想我找到了一种方法来做这件事,但它只是有时有效。(或者它可能不起作用,但有时确实起作用。(详细信息如下:

  1. 我必须DropdownMenu2组件,displayonMouseEnter/Leave事件切换。此组件(我的下拉菜单(包含在<NavLink>菜单项中
  2. 我希望下拉菜单在点击菜单项后消失,所以在<Navlink>中我创建了触发handleClickonClick事件。此函数将click变量-设置为具有display:none的CSSclassName。CCD_ 10然后被传递到包含下拉菜单的CCD_
  3. 为了在鼠标悬停时再次切换下拉菜单display,我必须从div中去掉click类。为此,我创建了具有click依赖关系的useEffect钩子,因此每当click状态更改时,它就会触发。这个钩子内的函数-更改click的值,因此它不再表示CSSdisplay:none类。因此,在(2.(-包含下拉菜单的div具有display:none之后,取消显示,并且useEffect擦除该内容-使其做好悬停准备

问题:

这只在某些情况下有效——有时useEffectonClick之后被触发得太快,以至于下拉菜单甚至不会下降。(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,要么在设置状态时获取最新状态。

  1. setTimeout溶液-
useEffect(() => {
setTimeout(() => {
setClick("")
},2000)
  1. 尝试在更新下一个状态时始终获取最新状态
useEffect(() => {
console.log("[usEffect]")
setClick((clickLatest) => "");
}, [click]);

const handleClick = () => setClick((clickLatest) => className); 

此回调将帮助useState等待最新状态,然后进一步更新状态。

我想我刚刚找到了一个简单的解决方案。我不明白为什么useEffect似乎在随机时序中工作,但在其中使用setTimeOut,并延迟setClick-的执行似乎就可以了。

useEffect(() => {
setTimeout(() => {
setClick("")
},2000)

最新更新