reactjsreact-routertoggleuse-statereact-toggle

How to toggle active class of tabs in React?


I made 2 buttons 'Login' and 'Register'. I wanna toggle the active class on these button if the user wanna login or register. Here is the code.

const [buttonStatus, setButtonStatus] = useState('');

const buttonStatusHandler = () =>{

if(buttonStatus === ''){
  setButtonStatus('active')
}

else{
  setButtonStatus('')
}

}

JSX

<div className='button_wrap'>
     <button className={buttonStatus} onClick={buttonStatusHandler}>Login</button>
     <button className={buttonStatus} onClick={buttonStatusHandler}>Register</button>      
</div>

Output Im trying

enter image description here

Active class would be the yellow button.


Solution

  • You can toggle the state and use a class merger function to conditionally toggle the active class for the respective buttons.

    codesandbox

    import { useState } from "react";
    
    export default function App() {
      const [buttonStatus, setButtonStatus] = useState("login");
    
      return (
        <div className="button_wrap">
          <button
            className={cm(buttonStatus, buttonStatus === "login" && "active")}
            onClick={() => setButtonStatus("login")}
          >
            Login
          </button>
          <button
            className={cm(buttonStatus, buttonStatus === "register" && "active")}
            onClick={() => setButtonStatus("register")}
          >
            Register
          </button>
        </div>
      );
    }
    
    function cm(...args) {
      return args.filter((v) => v).join(" ");
    }
    

    Explanation of the cm function

    The class merger function takes in any amount of arguments as an array args. After that it iterates while filtering the class names. Each class name is checked for truthyness and if it's not truthy it gets filtered. Therefore, you can pass conditional expressions as arguments and if the condition is false, the class name will be filtered. After that the filtered class array is joined with " " resulting in a valid html class attribute value.