gpt4 book ai didi

reactjs - React - 我的用于在元素外部单击的自定义 Hook 有什么问题吗?

转载 作者:行者123 更新时间:2023-12-02 19:01:11 25 4
gpt4 key购买 nike

我有一个自定义 Hook ,用于在菜单中的元素外部单击。发生的情况是:当我单击“打开菜单”时,它会打开菜单,当我单击外部时,它会关闭它(一切都很好),但是当我再次单击“打开菜单”按钮以关闭它时(打开它后),它将其关闭一秒钟,然后再次打开。我一直在寻找原因,但找不到。任何帮助都会很棒。抱歉,如果我没有很好地表达我的问题,我不知道如何问得更清楚:)谢谢!!

const { useState, useRef } = React;

const App = () => {
const [showMenu, setShowMenu] = React.useState(false)

return (
<div>
<div className="menu-section-conatainer">
<button
className={"menu-link"}
onClick={() => {
setShowMenu(true)
}}
name={title}
>
open menu
</button>
</div>

<Menu
showState={showMenu}
clickHandler={setShowMenu}
>
{children}
</Menu>
</div>
)
}

const Menu = ({ children, clickHandler, showState}) => {
const ref = useRef()
useOnClickOutside(ref, () => clickHandler(false))

return (
<div
className="menu-expanded-wrapper"
>
<div ref={ref} className="menu-expanded">
{children}
</div>
</div>
)
}

const useOnClickOutside = (ref, handler) => {
React.useEffect(() => {
const listener = event => {
if (!ref.current || ref.current.contains(event.target)) {
return
}
handler(event)
}

document.addEventListener("mousedown", listener)
document.addEventListener("touchstart", listener)

return () => {
document.removeEventListener("mousedown", listener)
document.removeEventListener("touchstart", listener)
}
}, [ref, handler])
}

最佳答案

在菜单已打开的情况下单击按钮时,菜单组件关闭然后立即再次打开的原因是,当您单击按钮时,会调用 useOnClickOutside 中的监听器(并关闭菜单)然后调用按钮上的 onClick 函数(并打开菜单)。

您可以通过将 useOnClickOutside 的使用移至 App 组件并将 ref 放置在作为按钮和菜单的父元素的元素上来解决此问题出于“外部”的目的,按钮上的点击将被忽略。此外,无论如何,这可能是一个更好的结构,因此打开/关闭逻辑仅位于 App 组件中。

然后您应该更新按钮的 onClick 函数,以便它切换 showMenu 而不是仅仅将其值设置为 true。您只需使用 setShowMenu(prev => !prev) 即可完成此操作。

这是一个例子:

const App = () => {
const [showMenu, setShowMenu] = React.useState(false)
const ref = React.useRef()
useOnClickOutside(ref, () => setShowMenu(false))

return (
<div ref={ref}>
<div className="menu-section-conatainer">
<button
className={"menu-link"}
onClick={() => {
setShowMenu(prev => !prev)
}}
name="Toggle Menu"
>
{showMenu ? "Hide Menu" : "Show Menu"}
</button>
</div>

<Menu showState={showMenu}>
Menu Items
</Menu>
</div>
)
}

const Menu = ({ children, showState}) => {
return (
<div className="menu-expanded-wrapper">
<div className={ showState ? "menu-expanded" : "menu-collapsed" }>
{children}
</div>
</div>
)
}

useOnClickOutside Hook 没有任何更改。

关于reactjs - React - 我的用于在元素外部单击的自定义 Hook 有什么问题吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65553853/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com