javascript - 一次只显示一个下拉菜单
问题描述
您好,我有一个下拉菜单,我希望一次只打开菜单上的一项,但是我无法理解在打开状态时仅将一项设为真的逻辑,其他人为假我试图使用我的 useState 和我的所有下拉菜单创建一个数组,但我无法想象一个解决方案:
代码
const [dropDownItems, setDropDownItem] = useState({
dropdown_home: false,
dropdown_about: false,
});
const updateDropDownItem = (dropDownItem, value) => {
let existingValues = JSON.parse(JSON.stringify(dropDownItems));
existingValues[dropDownItem] = value;
setDropDownItem(existingValues);
};
<NavLi
onClick={() => {
updateDropDownItem(
'dropdown_home',
!dropDownItems.dropdown_home,
);
}}
>
<Link to="/">One</Link>
{dropDownItems.dropdown_home ? (
<ul>
<li>
<a className="active" href="#Create Page">
Create Page
</a>
</li>
<li>
<a href="#Manage Pages">Manage Pages</a>
</li>
</ul>
) : null}
</NavLi>
<NavLi
onClick={() => {
updateDropDownItem(
'dropdown_about',
!dropDownItems.dropdown_about,
);
}}
>
<Link to="../about">Two</Link>
{dropDownItems.dropdown_about ? (
<ul>
<li>
<a className="active" href="#Create Page">
Create Page
</a>
</li>
<li>
<a href="#Manage Pages">Manage Pages</a>
</li>
</ul>
) : null}
</NavLi>
问题::
我想不出一种解决方案,只留下一个项目为真而其他项目为假..
解决方案
在管理与当前单击的项目相对应的状态变量时,您似乎没有将其他人重置为false
,因此您的代码应该看起来像:
const updateDropDownItem = dropDownItem => {
const dropDownItemsCopy = {...dropDownItems}
Object.keys(dropDownItemsCopy).forEach(key => dropDownItemsCopy[key] = key == dropDownItem)
setDropDownItem(dropDownItemsCopy)
}
这样,您只需要传递被单击的确切项目,如下所示(对于每个项目):
onClick={() => updateDropDownItem('dropdown_about')}
以下是作为概念证明的快速演示:
const { useState } = React,
{ render } = ReactDOM,
rootNode = document.getElementById('root'),
menu = ['menu1', 'menu2', 'menu3', 'menu4']
const MenuBar = ({menuItems}) => {
const [visibleMenu, setVisibleMenu] = useState(menuItems.reduce((r,e) => (r[e] = false, r), {})),
onUpdateVisibility = item => {
const visibleMenuCopy = {...visibleMenu}
Object.keys(visibleMenuCopy).forEach(key => visibleMenuCopy[key] = key == item)
setVisibleMenu(visibleMenuCopy)
}
return (
<div>
{
menuItems.map(item => (
<span
key={item}
onClick={() => onUpdateVisibility(item)}
>
{item}
</span>
))
}
<br/><br/>
{JSON.stringify(visibleMenu)}
</div>
)
}
render(<MenuBar menuItems={menu} />, rootNode)
span {
margin-left: 20px;
margin-bottom: 50px;
border: 1px solid green;
padding: 5px;
cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.11.0/umd/react-dom.production.min.js"></script><div id="root"></div>
推荐阅读
- reactjs - TypeScript 反应钩子
- javascript - 无法检查文档是否存在于云 Firestore 数据库中并使用 reactjs
- python - 自定义 Django 表单 - 根据请求修改已清理的数据
- php - 允许将 WooCommerce 中特定用户角色的相同父类别的产品添加到购物车
- ruby-on-rails - 这是做什么的:`const { $ } = require("@rails/ujs");` 在我的 Rails 应用程序中?它似乎导致错误
- openlayers - 将给定点移动 X,Y 米 Openlayers
- python - AttributeError:“MySQLConverter”对象没有属性“_tuple_to_mysql”
- php - PHP 对象的属性可以是数组吗?如果是这样,我如何从对象中添加它?
- azure - Azure Purview 无法对 Azure 数据资源管理器数据库进行分类
- sql-server - 弹性作业代理立即在逻辑应用中的作业超时