Skip to content
Advertisement

React: How to set a component in ‘active’ state one at a time, and remove ‘active’ from all other component on click?

I want to set a particular component as active on click, and update the active component when some other component is clicked. Currently, both the components are remaining in active state. I want to remove active state from previously clicked component.

 const [activeComponent, setActiveComponent] = useState(null);

  const updateActiveComponent = (e, active_component) => {
    if (active_component.id != activeComponent?.id) {
      setActiveComponent(active_component);
    } else {
      closeActiveComponent();
    }
  };
  const closeActiveComponent = () => {
    setActiveComponent(null);
  };
<MyComponent
        key={index}
        card={card}
        clickHandler={updateActiveComponent}
      />

Advertisement

Answer

To make it general, let’s imagine that you have not just two components, but any number of components.

We have 2 cases:

  1. Components work as a radio buttons. Only one component at a time can be active.
  2. Components work as a checkbox buttons. Multiple components can be at active state.

As I understood, you have the first case. So, to make it working we need to store the id of active component.

import { useState } from 'react'

const Component = ({ isActive, onClick }) => {
    return <div onClick={onClick}> {isActive ? 'Active' : 'Not active'} </div>
}

const Page = () = {
    // -1 means that we have not set any component to the active state
    const [activeElement, setActiveElement] = useState(-1);

    const updateActiveElement = (id) => {
        setActiveElement(activeElement !== id ? id : -1);
    }

    return (
        <div>
            <Component active={0 === activeElement} onClick={() => updateActiveElement(0)} />
            <Component active={1 === activeElement} onClick={() => updateActiveElement(1)} />
        </div>
    );
}

For a checkbox type case, we need to store the state of each component individually, means, we need to create the array of each components state.

import { useState } from 'react'

const Component = ({ isActive, onClick }) => {
    return <div onClick={onClick}> {isActive ? 'Active' : 'Not active'} </div>
}

const Page = ({ amountComponents }) = {
    const [elementStates, setElementStates] = useState(Array(amountComponents).fill(false));

    const updateActiveElement = (id) => {
        setActiveElement(elementStates.map((isActive, index) => index === id ? !isActive : isActive ));
    }

    return (
        <div>
            {elementStates.map((isActive, id) => (
                <Component active={isActive} onClick={() => updateActiveElement(id)} />
            )}
        </div>
    );
}
Advertisement