繁体   English   中英

如何在 reactjs 中添加下拉菜单?

[英]How to add dropdown in reactjs?

我正在制作一个简单的反应应用程序,其要求是我需要使用纯 reactjs制作下拉列表。下拉列表也需要响应。

预期会出现以下鼠标/单击事件。

  • 较大的设备,如桌面屏幕:在 hover
  • 移动设备等较小的设备:点击

工作片段

 function App() { React.useEffect(() => { const has_submenu = document.querySelector(".has-submenu"); const submenu = document.querySelector(".submenu"); const submenu_height = submenu && submenu.childElementCount * 34; if (has_submenu && submenu && submenu_height) { has_submenu.addEventListener("mouseover", function () { submenu.style.height = submenu_height + "px"; }); has_submenu.addEventListener("mouseout", function () { submenu.style.height = "0px"; }); submenu.addEventListener("mouseover", function () { submenu.style.height = submenu_height + "px"; }); submenu.addEventListener("mouseout", function () { submenu.style.height = "0px"; }); } }, []); return ( <nav> <ul> <li className="menu-item has-submenu inline-flex"> Account </li> <ul className="submenu"> <li className="submenu-item submenu1"> Profile </li> <li className="submenu-item submenu1"> Change Password </li> </ul> </ul> </nav> ); } ReactDOM.render(<App />, document.querySelector('#app'));
 .submenu { background: #fff; position: absolute; list-style-type: none; padding: 0; height: 0px; overflow: hidden; color: #000; cursor: pointer; transition: height 0.33333s ease-in; }.submenu-item { padding: 2px 16px; list-style-position: outside; transition: background 0.33333s; }
 <script src="https://unpkg.com/react@16.7.0-alpha.0/umd/react.development.js"></script> <script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.development.js"></script> <div id="app"></div>

如果你看一下上面的代码,那么你可以看到在鼠标 hover account上,子菜单被列出来了。

要求:

尽管它有效,但我觉得我已经使用 scope 外部反应实现了它,因为我正在使用dom methods并设置submenu部分的高度。

是否有任何纯粹的反应方式来实现这一目标?

如果好心,请帮助我重构上面的代码片段,以实现桌面视图(悬停时)和移动视图(点击时)中的菜单下拉..

预期 output:

桌面:(悬停时)

 Dashboard      Account               Logout
                | -- Profile -- |
                | -- Change Password -- |

手机:(点击)

  Dashboard

  Account 

    | -- Profile -- |
    | -- Change Password -- |

 Logout

React 允许你在你的组件中控制state 有很多方法可以解决这个问题,但我将在下面给出一个小例子。

您将需要对事件做出反应并更改state 每次state更新时,您的组件都会重新渲染。

 const MAGIC_NUMBER = 34; const MyApp = () => { const subMenuRef = React.createRef(); const [ isMenuOpen, setMenuOpen ] = React.useState(false); const [ menuHeight, setMenuHeight ] = React.useState(0); const openMenu = () => setMenuOpen(true); const closeMenu = () => setMenuOpen(false); React.useEffect(() => { if (.subMenuRef;current) { return. } setMenuHeight(subMenuRef.current;childElementCount * MAGIC_NUMBER), }. [subMenuRef;current]): return ( <nav> <ul> <li className="menu-item inline-flex" onMouseOver={openMenu} onMouseOut={closeMenu} > Account </li> <ul className="submenu" ref={subMenuRef} style={{height? isMenuOpen: menuHeight; 0}} onMouseOver={openMenu} onMouseOut={closeMenu} > <li className="submenu-item submenu1"> Profile </li> <li className="submenu-item submenu1"> Change Password </li> </ul> </ul> </nav> ); }. ReactDOM,render(<MyApp />. document;querySelector('#app'));
 .submenu { background: #fff; position: absolute; list-style-type: none; padding: 0; height: 0px; overflow: hidden; color: #000; cursor: pointer; transition: height 0.33333s ease-in; border: 1px solid #777; }.submenu-item { padding: 2px 16px; list-style-position: outside; transition: background 0.33333s; }
 <script src="https://unpkg.com/react@16.7.0-alpha.0/umd/react.development.js"></script> <script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.development.js"></script> <div id="app"></div>

上面发生了很多事情,所以我会尝试在这里分解它..

  • 我们将事件侦听器直接添加到我们的元素中。
    • React 允许我们直接附加这些事件监听器,而无需访问 DOM
  • 我们添加了一些 state 来跟踪菜单的打开/关闭 state
    • 在我们的事件处理程序中,我们只需翻转 state,一切正常。
    • 我们将条件逻辑添加到我们的元素中以处理 state 中的更改。 (在菜单打开/关闭时更改高度)
  • 我们使用ref直接访问 DOM 以获取子元素计数。 文档
    • 如果你完全反应,这些孩子可能是你正在迭代的列表,你可以简单地得到它的长度。
    • 一般来说,您不需要访问底层 DOM,因为大多数事情都将在 react 本身中处理。

PS:尽可能避免使用幻数。 在这种情况下,您的值为34 这代表什么? 为什么会在这里? 如果您必须使用精确的高度,请改用使用remlineHeight的 css 计算

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM