'I am trying to give an active className to mapped data when I click. Currently the previous active class doesn't change when i click on another text

Parent component

Here is the mapped function

function SubHeader() {
  const categories = category?.data?.data;
  return (
            {categories?.map((data) => (

          <Smaller data={data} />

        ))}  );
}

Child component Here is where I am using the state to control the color of the text when it is clicked. Not sure I can figure what isn't right.

function Smaller({ data }) {
  const [active, setActive] = useState(false);
   const colorPicker = (dataId) => {
    setActive(dataId ? !active : active);
  };

  return (
    <Text
      color={active ? 'brand.blue' : 'brand.dark'}
      onClick={() => colorPicker(data?.id)}
    >
      {data?.name}
    </Text>
  );
}


Solution 1:[1]

The issue is when you click on another text, it doesn't change the active state of other / previous texts. So you're just toggling the active class of each component but it doesn't "untoggle" anywhere. I found a way to solve this but I used a simple example because I didn't have your data.

Solution:

  1. Each child component should have an ID.
  2. Check if the child component's ID matches the activeElementID.

Parent Component

function SubHeader() {
  const [activeElementID, setActiveElementID] = useState()
  const categories = category?.data?.data;

  return (
    {categories?.map((data) => {
      <Smaller data = {data} id = {data?.id} activeElementID={activeElementID} setActiveElementID={setActiveElementID} />
    })}
  )
}

Child Component

function Smaller({data, id, activeElementID, setActiveElementID}) {

  function clicked() {
    setActiveElementID(id)
  }

  return (
    <p onClick={clicked} className={activeElementID === id ? "blue" : "red"}>{data}</p>
  )
}

Furthermore, I would also recommend checking the data instead of using the "?" operation. For example, category?.data and data?.data

Because you are saying that you are sure the data exists. You can do this instead.

const categories = category.data.data
if (categories) {
   return (....)
}

Hope this helps!

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 Shahmir Varqha