Reactjs 在单击另一个元素时切换元素上的类

Reactjs 在单击另一个元素时切换元素上的类,reactjs,Reactjs,我有这个成分。我希望每当我单击类为“btn”的a标记时,在同一li元素中添加/切换类为“open”的div,类为“smenu”。我天真地实现了它,如下所示,但我相信应该有另一种更有效的方法。任何提示都将不胜感激。提前谢谢 import React, { useState } from "react"; const AccordioMenu = () => { const [activeP, setActiveP] = useState(false); const [activeM

我有这个成分。我希望每当我单击类为“btn”的a标记时,在同一li元素中添加/切换类为“open”的div,类为“smenu”。我天真地实现了它,如下所示,但我相信应该有另一种更有效的方法。任何提示都将不胜感激。提前谢谢

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;
import React,{useState}来自“React”;
const AccordioMenu=()=>{
const[activeP,setActiveP]=useState(false);
const[activeM,setActiveM]=useState(false);
常数toggleActiveP=()=>{
setActiveP(!activeP);
};
常量toggleActiveM=()=>{
setActiveM(!activeM);
};
让btnclassesP=['smenu']
if(activeP){
BTNClassep.push(“打开”)
}
让btnclassem=['smenu']
if(activeM){
BTNClassem.push(“打开”)
}
返回(
  • ); }; 导出默认手风琴菜单;
    如果您想进一步简化此过程,可以只使用一个状态值,这样组件就可以共享一个真实来源

    让我们有一个存储标识符数组的状态。每个标识符都与一组不同的链接相关联。我们将使用“message”和“profile”作为标识符。当然,如果数组中没有任何内容,则应折叠所有子链接

    然后,我们可以只使用事件处理程序将标识符添加/删除到
    状态
    数组中。最后,我们可以使用内联样式来确定与标识符对应的链接集是否应该包括
    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;
    
    import React,{useState}来自“React”;
    const AccordioMenu=()=>{
    const[selectedItems,setSelectedItems]=useState([])
    //事件处理程序接受标识符字符串作为参数
    const handleSelect=(标识符)=>{
    //创建原始状态的副本以避免状态突变
    const selectedItemsCopy=[…selectedItems]
    //检查已传递的标识符是否已存在于状态中
    如果(选择编辑透视包括(标识符)){
    //它已经存在,这意味着菜单链接已展开
    const foundIndex=selecteditemscope.indexOf(标识符)
    //您已单击它以隐藏它。因此,请从状态中删除该标识符
    选择编辑透视。拼接(foundIndex,1)
    设置SelectEdItems(SelectEdItems)
    }否则{
    //如果在状态中找不到标识符,则添加它。
    setSelectedItems([…selectedItems,标识符])
    }
    }
    返回(
    
  • //设置处理程序以传递标识符
  • //设置处理程序以传递标识符
  • ); }; 导出默认手风琴菜单;
    如果您想进一步简化此过程,可以只使用一个状态值,这样组件就可以共享一个真实来源

    让我们有一个存储标识符数组的状态。每个标识符都与一组不同的链接相关联。我们将使用“message”和“profile”作为标识符。当然,如果数组中没有任何内容,则应折叠所有子链接

    然后,我们可以只使用事件处理程序将标识符添加/删除到
    状态
    数组中。最后,我们可以使用内联样式来确定与标识符对应的链接集是否应该包括
    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;
    
    import React,{useState}来自“React”;
    const AccordioMenu=()=>{
    const[selectedItems,setSelectedItems]=useState([])
    //事件处理程序接受标识符字符串作为参数
    const handleSelect=(标识符)=>{
    //创建原始状态的副本以避免状态突变
    const selectedItemsCopy=[…selectedItems]
    //检查已传递的标识符是否已存在于状态中
    如果(选择编辑透视包括(标识符)){
    //它已经存在,这意味着菜单链接已展开
    const foundIndex=selecteditemscope.indexOf(标识符)
    //您已单击它以隐藏它。因此,请从状态中删除该标识符
    选择编辑透视。拼接(foundIndex,1)
    设置SelectEdItems(SelectEdItems)
    }否则{
    //如果在状态中找不到标识符,则添加它。
    setSelectedItems([…selectedItems,标识符])
    }
    }
    返回(
    
  • //设置处理程序以传递标识符
  • //设置处理程序以传递标识符
  • ); }; 导出默认手风琴菜单;
    是一个很好的答案,可以使用

    我只想使用
    useReducer
    提供一种不同的方法来处理相同的场景

    如果有多个状态相互协同工作,有时使用减速器“共同定位”相关状态更改会很容易

    import React,{useReducer}来自“React”;
    常量初始状态={
    profileClass:'smenu',
    菜单类:“smenu”,
    };
    //是一个很好的答案

    我只想使用
    useReducer
    提供一种不同的方法来处理相同的场景

    如果你有多个州