React hooks - 在 useEffect 中设置超时但能够从鼠标事件中清除它?
React hooks - Set a timeout inside useEffect but be able to clear it from a mouse event?
这是一个经典的菜单案例,点击按钮打开,如果没有按钮在 5 秒内隐藏 activity。我们有 2 个状态变量。 open 和 active,对应两种不同的状态 = menu is open, and active (being used)。我使用单击按钮设置打开变量,然后实际上我开始了 5 秒超时。现在,如果用户将鼠标悬停在菜单上,我将活动 属性 设置为 true 并尝试清除超时。但这是行不通的。意思是,超时变量在应该清除它的代码中始终为 null。
这里有一些代码可以帮助您理解:
let [open, openMenu] = useState(false)
let [active, activateMenu] = useState(false)
let timer = null;
useEffect(() => {
if(open && !active) {
timer = setTimeout(() => setOpen(false), 5000)
}
if(open && active) {
if(timer) {
clearTimeout(timer)
}
}
}, [open, active])
// Triggered via the UI on a button click
openMenuhandler() {
setOpen(true)
}
// Triggered via the UI on mouseenter
// identifies that the menu is being used, when mouse is over it
setMenuActive() {
activateMenu(true)
}
// Triggered via the UI on mouseleave
setMenuInActive() {
activateMenu(false)
}
// other code here on
现在超时永远不会被清除。无论如何,菜单会在 5 秒内隐藏。还有另一种方法吗?我什至尝试将 clearTimeout 移至 mouseLeave,但即便如此,计时器仍为空。如何解决这个问题?请帮忙。
只要您的组件 re-renders,timer
变量将为 re-declared,初始值为 null
。因此,当 useEffect
钩子在其任何依赖项更改时执行时,timer
变量为 null
.
您可以通过确保 timer
变量的值在组件的 re-renders 中保持不变来解决问题。要在 re-renders 中保留该值,请使用 useRef
挂钩保存 setTimeout
的 ID 或将其保存在状态中,即 useState
挂钩。
这是一个经典的菜单案例,点击按钮打开,如果没有按钮在 5 秒内隐藏 activity。我们有 2 个状态变量。 open 和 active,对应两种不同的状态 = menu is open, and active (being used)。我使用单击按钮设置打开变量,然后实际上我开始了 5 秒超时。现在,如果用户将鼠标悬停在菜单上,我将活动 属性 设置为 true 并尝试清除超时。但这是行不通的。意思是,超时变量在应该清除它的代码中始终为 null。
这里有一些代码可以帮助您理解:
let [open, openMenu] = useState(false)
let [active, activateMenu] = useState(false)
let timer = null;
useEffect(() => {
if(open && !active) {
timer = setTimeout(() => setOpen(false), 5000)
}
if(open && active) {
if(timer) {
clearTimeout(timer)
}
}
}, [open, active])
// Triggered via the UI on a button click
openMenuhandler() {
setOpen(true)
}
// Triggered via the UI on mouseenter
// identifies that the menu is being used, when mouse is over it
setMenuActive() {
activateMenu(true)
}
// Triggered via the UI on mouseleave
setMenuInActive() {
activateMenu(false)
}
// other code here on
现在超时永远不会被清除。无论如何,菜单会在 5 秒内隐藏。还有另一种方法吗?我什至尝试将 clearTimeout 移至 mouseLeave,但即便如此,计时器仍为空。如何解决这个问题?请帮忙。
只要您的组件 re-renders,timer
变量将为 re-declared,初始值为 null
。因此,当 useEffect
钩子在其任何依赖项更改时执行时,timer
变量为 null
.
您可以通过确保 timer
变量的值在组件的 re-renders 中保持不变来解决问题。要在 re-renders 中保留该值,请使用 useRef
挂钩保存 setTimeout
的 ID 或将其保存在状态中,即 useState
挂钩。