'React Toggle open and close using onclick on map function

I have an onClick in map function, if I click onClick it will change state of all map item not that item which I clicked. I am using useState hook.

const [open, setOpen] = useState(true);

{
  FilterAvailable.map((item, id) => {
    return (
      <li className="filterItem">
        <div
          className="filterBtn flex align-center justify-between"
          onClick={() => setOpen(!open)}
        >
          <h2>{item.catogery}</h2>
          <div>
            {open ? (
              <IoIosArrowDown className="downArrow" />
            ) : (
              <IoIosArrowUp className="downArrow" />
            )}
          </div>
        </div>

        {item.options.map(option => {
          return (
            <>
              {open && (
                <ul className="filterOption">
                  <li className="filterOptionitem">
                    <button>{option}</button>
                  </li>
                </ul>
              )}
              {/* <div className="hrLine"></div> */}
            </>
          );
        })}
      </li>
    );
  });
}

I want to open only those item option which click.



Solution 1:[1]

Put the index inside state on onclick , inside map check if state index equals to map index and you are done

Solution 2:[2]

Your state is in the wrong place, you need to break the component and have a open state per filterableItem


const Filters = () => {
  return FilterAvailable.map((item, id) => {
    return <FilterItem item={item} />;
  });
};

const FilterItem = ({ item }) => {
  const [open, setOpen] = useState(true);

  return (
    <li className="filterItem">
      <div
        className="filterBtn flex align-center justify-between"
        onClick={() => setOpen(!open)}
      >
        <h2>{item.catogery}</h2>
        <div>
          {open ? (
            <IoIosArrowDown className="downArrow" />
          ) : (
            <IoIosArrowUp className="downArrow" />
          )}
        </div>
      </div>

      {item.options.map(option => {
        return (
          <>
            {open && (
              <ul className="filterOption">
                <li className="filterOptionitem">
                  <button>{option}</button>
                </li>
              </ul>
            )}
          </>
        );
      })}
    </li>
  );
};


Solution 3:[3]

Consider moving the mapped elements to their own component with props - then you create and set your open and closed state there.

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 n1koloza
Solution 2 Shujaat
Solution 3 coderMatt