'Conditional classname not changing even after value changes

I'm building a page with two tabs. When one tab is clicked, the other tab should have the className="nav-link active" and the other tab should switch to className="nav-link" and vice-versa.

Here's my code:

import react from 'react'

const account = () => {
    const [activeTab, tabActive] = react.useState("true")
    return (
        <>
            <div className='container my-5'>
                <ul className="nav nav-tabs">
                    <li className="nav-item">
                        <button type="button" className={"nav-link " + (activeTab?'active':'')} onClick={() => tabActive("true")}>Profile details</button>
                    </li>
                    <li className="nav-item">
                        <button type="button" className={"nav-link " + (activeTab?'':'active')}  onClick={() => tabActive("false")}>Select Colleges</button>
                    </li>
                </ul>
            </div>
            <div className='container my-5'>
                {
                    activeTab === "true" && <p>Value is true</p>
                }
                {
                    activeTab === "false" && <p>Value is false</p>
                }
            </div>
            
        </>
    )
}

export default account

The aforementioned code should be able to do what I expect, however, I can't get the active class removed and added to the buttons as expected. It's either being applied to both buttons at the same time or two none at all.



Solution 1:[1]

Non-empty strings are always truthy. Use booleans instead.

const account = () => {
  const [activeTab, tabActive] = react.useState(true);

  return (
    <>
      <div className='container my-5'>
        <ul className="nav nav-tabs">
          <li className="nav-item">
            <button
              type="button"
              className={"nav-link " + (activeTab ? 'active' : '')}
              onClick={() => tabActive(true)}
            >
              Profile details
            </button>
          </li>
          <li className="nav-item">
            <button
              type="button"
              className={"nav-link " + (activeTab ? '' : 'active')}
              onClick={() => tabActive(false)}
            >
              Select Colleges
            </button>
          </li>
        </ul>
      </div>
      <div className='container my-5'>
        {activeTab ? <p>Value is true</p> : <p>Value is false</p>}
      </div>
    </>
  )
};

Update

For more than 2 tabs use an index or GUID, anything that uniquely identifies a tab, to store in state for the active tab, and check this value for matching when rendering.

Example:

const account = () => {
  const [activeTab, tabActive] = react.useState(0);

  return (
    <>
      <div className='container my-5'>
        <ul className="nav nav-tabs">
          <li className="nav-item">
            <button
              type="button"
              className={"nav-link " + (activeTab === 0 && 'active')}
              onClick={() => tabActive(0)}
            >
              Profile details
            </button>
          </li>
          <li className="nav-item">
            <button
              type="button"
              className={"nav-link " + (activeTab === 1 && 'active')}
              onClick={() => tabActive(1)}
            >
              Select Colleges
            </button>
          </li>
          <li className="nav-item">
            <button
              type="button"
              className={"nav-link " + (activeTab === 2 && 'active')}
              onClick={() => tabActive(2)}
            >
              Select Something Else
            </button>
          </li>
        </ul>
      </div>
      <div className='container my-5'>
        {activeTab === 0 && <p>Active tab is 0</p>}
        {activeTab === 1 && <p>Active tab is 1</p>}
        {activeTab === 2 && <p>Active tab is 2</p>}
      </div>
    </>
  )
};

Edit conditional-classname-not-changing-even-after-value-changes

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1