Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

React.js: How to change icon when item in the list is clicked?

I’m trying to implement a logic, where based on clicked item, arrow down icon changes to arrow-up and if user clicks 2nd time to the same row should again change.
I tried to trigger it based on the index of clicked item, but doesn’t work properly.
Also tried to change the icons based on boolean state change like here

const handleClick = () => {
    setOpen(!open);
  };

But this approach changes state for all icons in the state.

Here is the code and sandbox link.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

import React, { useState } from "react";
import { ListGroup } from "react-bootstrap";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faAngleUp, faAngleDown } from "@fortawesome/free-solid-svg-icons";

export const defaultListData = [
  {
    name: "Dapibus ac facilisis in"
  },
  {
    name: "Morbi leo risus"
  },
  {
    name: "Porta ac consectetur ac"
  },
  {
    name: "Porta ac doesfvsaard  asdas"
  }
];

function UserSettings() {
  const [open, setOpen] = useState(false);
  const [selectedIndex, setSelectedIndex] = useState(0);

  const handleClick = () => {
    setOpen(!open);
  };

  function handleTests(index) {
    setSelectedIndex(index);
  }

  return (
    <div>
      {defaultListData.map((category, i) => (
        <ListGroup key={category.name} variant="flush">
          <ListGroup.Item
            onClick={(e) => handleTests(i)}
            style={{ display: "flex", gap: "50px" }}
          >
            {category.name}

            <FontAwesomeIcon
              style={{ color: "green", cursor: "pointer" }}
              icon={selectedIndex === i ? faAngleDown : faAngleUp}
            />
          </ListGroup.Item>
        </ListGroup>
      ))}
    </div>
  );
}

export default UserSettings;

Any help will be appreciated

>Solution :

You want to toggle change the selectedIndex depending on whether the clicked item is already open. The better way would be to move the Item to a separate component that has its own open state:


const Item = (props) => {
  const [open, setOpen] = useState(false);

  const handleClick = () => {
    setOpen((prev) => !prev);
  };

  return (
    <ListGroup.Item
      onClick={(e) => handleClick()}
      style={{ display: "flex", gap: "50px" }}
    >
      {props.category.name}

      <FontAwesomeIcon
        style={{ color: "green", cursor: "pointer" }}
        icon={open ? faAngleDown : faAngleUp}
      />
    </ListGroup.Item>
  );
};

function UserSettings() {
  return (
    <div>
      {defaultListData.map((category, i) => (
        <ListGroup key={category.name} variant="flush">
          <Item category={category} />
        </ListGroup>
      ))}
    </div>
  );
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading