javascript - React hooks - 在 useEffect 中设置超时但能够从鼠标事件中清除它?

标签 javascript reactjs react-hooks timeout

这是一个经典的菜单案例,点击按钮即可打开,如果没有事件,5秒后隐藏。我们有 2 个状态变量。打开和事件,对应两种不同的状态=菜单打开,并且事件(正在使用)。我使用单击按钮设置 open 变量,然后实际上开始 5 秒超时。现在,如果用户将鼠标悬停在菜单上,我将 active 属性设置为 true 并尝试清除超时。但这是行不通的。这意味着,超时变量在应该清除它的代码中始终为空。

这里有一些代码可以帮助您理解:

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,但即使如此,计时器仍为空。如何解决这个问题?请帮忙。

最佳答案

每当您的组件重新渲染时,timer 变量都会被重新声明,初始值为 null。因此,当 useEffect 钩子(Hook)在任何依赖项发生更改时执行时,timer 变量将为 null

您可以通过确保 timer 变量的值在组件的重新渲染过程中保持不变来解决该问题。要在重新渲染时保留该值,请使用 useRef Hook 保存 setTimeout 的 id,或者将其保存在状态中,即 useState Hook .

关于javascript - React hooks - 在 useEffect 中设置超时但能够从鼠标事件中清除它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64463372/

相关文章:

javascript - Twitter-bootstrap 3 附加侧边栏菜单在向下滚动时未显示完整

javascript - 谷歌新工作表格式上的 XmlHttpRequest 状态 0

reactjs - REACT 未捕获的 TypeError .then 不是一个函数

node.js - 在前端向用户显示error.response.data作为消息

reactjs - 使用 React Hooks 重新渲染的次数过多

Javascript Promises 如何进行解析后清理

javascript - Div 不会调整大小

javascript - ReactJS 处理组件更改

javascript - react Hook : Can't send state from Child component to Parent component

reactjs - ReactJS 中的 WebSocket 正在使用空数组设置状态