Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

645
Views
React.js: ¿Cómo cambiar el icono cuando se hace clic en el elemento de la lista?

Estoy tratando de implementar una lógica, donde, según el elemento en el que se hizo clic, el ícono de arrow down cambia a arrow-up y si el usuario hace clic por segunda vez en la misma fila, debería cambiar nuevamente.
Intenté activarlo según el índice del elemento en el que se hizo clic, pero no funciona correctamente.
También intenté cambiar los íconos según el cambio de estado booleano como aquí

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

Pero este enfoque cambia de estado para todos los íconos en el estado.

Aquí está el código y el enlace del sandbox .

 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;

Cualquier ayuda será apreciada

about 4 years ago · Juan Pablo Isaza
3 answers
Answer question

0

Necesita mantener el estado para cada registro. Consulte el ejemplo a continuación.

 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"; function UserSettings() { const [open, setOpen] = useState(false); const [defaultListData, setDefaultListData] = useState([ { name: "Dapibus ac facilisis in", selected: false }, { name: "Morbi leo risus", selected: false }, { name: "Porta ac consectetur ac", selected: false }, { name: "Porta ac doesfvsaard asdas", selected: false } ]); const handleClick = () => { setOpen(!open); }; function handleTests(index) { let updateData = defaultListData.map((item, i) => { return index === i ? { ...item, selected: !item.selected } : item; }); setDefaultListData(updateData); } 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={category.selected ? faAngleDown : faAngleUp} /> </ListGroup.Item> </ListGroup> ))} </div> ); } export default UserSettings;
about 4 years ago · Juan Pablo Isaza Report

0

Desea alternar cambiar el índice selectedIndex dependiendo de si el elemento en el que se hizo clic ya está abierto. La mejor manera sería mover el Item a un componente separado que tenga su propio estado open :

 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> ); }
about 4 years ago · Juan Pablo Isaza Report

0

Esto sucede porque su ícono se cambia solo cuando se selectedIndex === i lo que significa que solo la fila en la que hizo clic será faAngleDown .

En este caso, un buen enfoque sería otra variable, como una bandera, en defaultListData y verificarla para representar el ícono correcto.

Ex.:

 export const defaultListData = [ { name: "Dapibus ac facilisis in", isOpen: false }, { name: "Morbi leo risus", isOpen: false }, { name: "Porta ac consectetur ac", isOpen: false }, { name: "Porta ac doesfvsaard asdas", isOpen: false } ];
about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!