reactjs - 单击另一个元素时切换元素上的类
问题描述
我有这个组件在反应。每当我单击带有类“btn”的标签时,我想在同一个 li 元素中添加/切换类“open”到带有类“smenu”的 div。我像下面这样天真地实现了它,但我相信应该有另一种更有效的方法。任何提示将不胜感激。提前致谢
import React, { useState } from "react";
const AccordioMenu = () => {
const [activeP, setActiveP] = useState(false);
const [activeM, setActiveM] = useState(false);
const toggleActiveP = () => {
setActiveP(!activeP);
};
const toggleActiveM = () => {
setActiveM(!activeM);
};
let btnclassesP = ['smenu']
if(activeP){
btnclassesP.push('open')
}
let btnclassesM = ['smenu']
if(activeM){
btnclassesM.push('open')
}
return (
<div className="middle">
<div className="menu">
<li className="item" id="profile">
<a className='btn' href="#" onClick={toggleActiveP}>
Profile
</a>
<div className={btnclassesP.join(' ')}>
<a href="">Posts</a>
<a href="">Pictures</a>
</div>
</li>
<li className="item" id="messages">
<a className="btn" href="#" onClick={toggleActiveM}>
Messages
</a>
<div className={btnclassesM.join(' ')}>
<a href="">New</a>
<a href="">Sent</a>
</div>
</li>
<li className="item" id="logout">
<a className="btn" href="#">
Logout
</a>
</li>
</div>
</div>
);
};
export default AccordioMenu;
解决方案
如果您想进一步简化这一点,您可以只使用单态值,这样组件就可以共享一个单一的事实来源。
让我们有一个存储标识符数组的状态。每个标识符都与一组不同的链接相关联。我们将使用“message”和“profile”作为标识符。自然,如果数组中没有任何内容,则所有子链接都应该折叠。
然后我们可以只使用一个事件处理程序将标识符添加/删除到state
数组中。最后,我们可以使用内联样式来确定与标识符对应的链接集是否应该包含open
该类。
import React, { useState } from "react";
const AccordioMenu = () => {
const [ selectedItems, setSelectedItems ] = useState([])
//event-handler accepts an identifer-string as an argument
const handleSelect = (identifier) => {
//creates a copy of the original state to avoid state-mutation
const selectedItemsCopy = [...selectedItems]
//check if the idenifier that was passed already exists in the state
if(selectedItemsCopy.includes(identifier)){
//it already exists, which means the menu-links are expanded
const foundIndex = selectedItemsCopy.indexOf(identifier)
//you've clicked it to hide it. so remove the identifier from the state
selectedItemsCopy.splice(foundIndex, 1)
setSelectedItems(selectedItemsCopy)
} else {
//if identifier was not found in state. then add it.
setSelectedItems([...selectedItems, identifier])
}
}
return (
<div className="middle">
<div className="menu">
<li className="item" id="profile">
//set up handler to pass identifier
<a className='btn' href="#" onClick={() => handleSelect("profile")}>
Profile
</a>
<div className={selectedItems.includes("profile") ? "smenu open" : "smenu"}>
<a href="">Posts</a>
<a href="">Pictures</a>
</div>
</li>
<li className="item" id="messages">
//set up handler to pass identifier
<a className="btn" href="#" onClick={() => handleSelect("message")}>
Messages
</a>
<div className={selectedItems.includes("messages") ? "smenu open" : "smenu"}>
<a href="">New</a>
<a href="">Sent</a>
</div>
</li>
<li className="item" id="logout">
<a className="btn" href="#">
Logout
</a>
</li>
</div>
</div>
);
};
export default AccordioMenu;
推荐阅读
- python - 将数据附加到 Pandas 全局数据框变量不会持续存在
- assembly - 从 16 位实模式 (x86) 切换到 32 位保护模式
- c++ - C++ 文件编译:-L 和 -I 参数不适用于 boost 库
- android - 如何使 (NotificationCompat.Builder) 在 API 级别 28 上工作?
- html - 如何将css添加到没有id或class的输入字段?
- django - 在 django 2.2 的 admin.py 中注册抽象类的派生子类
- android - 使用 aws cloudfront 滑动,抛出 403 错误,但是当我使用 okhttp 发出请求时,我得到了正确的响应
- python - 如何将列添加到 numpy 数组
- flutter - 此函数的返回类型为“Row”,但不以 return 语句结尾
- javascript - select2 我不想从 json 中获取数据