Skip to content

Change style of the text dynamically React js

I want to change some styles of the text of the tab for my navbar. I want to switch between pages whenever I click the on the tab. And for that I want that tab to be active. I have written code as:

Header.js

import React from "react";
import "./Header.css";
import Tab from "./Tab";

 const tabs = ["About", "Portfolio", "Blogs", "Contact"];

const Header = () => {
  const 
  return (
    <div className="header">
      {tabs.map((elem, indx) => {
        return <Tab key={indx} text={elem} />;
      })}
    </div>
  );
};

export default Header;

Header.css

.header {
  width: 100%;
  background-color: transparent;
  z-index: 1;
  color: white;
  padding: 1em;
  box-shadow: 2px 2px 2px 2px rgb(66, 65, 65);

  display: flex;
  gap: 2em;
  justify-content: flex-end;
}

Tab.js

import React, { useState } from "react";
import "./Tab.css";

const Tab = ({ text }) => {
  const [active, setActive] = useState(false);

  return (
    <div className="tab">
      <div
        className={`text ${active && "active"}`}
        onClick={() => setActive(true)}>
        {text}
      </div>
    </div>
  );
};

export default Tab;

Tab.css

.tab {
  padding: 0.3;
}

.text {
  font-size: 1.1rem;
}

.active {
  color: chocolate;
  border-bottom: 1px solid chocolate;
}

.text:hover {
  color: chocolate;
  cursor: pointer;
}

Now when I click the tab it becomes active and clicking another tab make both of them active but I want only one to be active. How can I change the code in order to achieve what I want?

Answer

You have to lift the active tab state from the Tab component to the Header one and set a callback that will be passed to the Tab component, in order to update the state in the parent.

You should end up with something like:

const tabs = ['About', 'Portfolio', 'Blogs', 'Contact']

const Header = () => {
  const [activeTab, setActiveTab] = useState('');
  
  const handleTabClick = useCallback((tab) => {
    setActiveTab(tab);
  }, []);
  
  return (
    <div className="header">
      {tabs.map((elem) => {
        return <Tab key={elem} text={elem} isActive={elem === activeTab} onTabClick={handleTabClick} />;
      })}
    </div>
  );
}

const Tab = ({ text, isActive, onTabClick }) => {
  return (
    <div className="tab">
      <div
        className={`text ${isActive && "active"}`}
        onClick={() => onTabClick(text)}
      >
        {text}
      </div>
    </div>
  );
}