Aquí está el componente:
import { useState, useEffect } from 'react' export default function AdminsComponent() { const [secondCard, setSecondCard] = useState(false) const toggleSetSecondCard = () => { setSecondCard(!secondCard) } const adminsComponent = adminData.map((user) => ( <li key={user.index} className="px-4 my-1 lg:pl-8 w-full scale-95 transform transition duration-500 hover:scale-100 text-left" onClick={toggleSetSecondCard} > // codehere </li> {secondCard && ( <div className="px-4 border-l-4 p-2 bg-accent-0 text-accent-8 pb-4 shadow-lg border-blue"> // ... codehere </div> )} )) return <ul>{adminsComponent}</ul> } Eliminé todas las cosas que tiene adentro para simplificar, pero básicamente creé una función useState en la que, cuando hago clic en cualquiera de los <li> representados, muestra el div dentro del
{secondCard && ()}
Pero está alternando el div para todos los <li> al mismo tiempo. Lo quiero individualmente solo para el <li> en el que hice clic. ¿Cómo podría lograr eso?
Cada li necesita tener su propio estado. Ya sea usando useState() con una matriz de valores booleanos asignados a los usuarios, o teniendo su propio componente, con su propio estado, como este:
import { useState } from "react"; const Card = (props) => { const [secondCard, setSecondCard] = useState(false); const toggleSetSecondCard = () => { setSecondCard(!secondCard); }; return ( <> <li key={props.user.index} className="px-4 my-1 lg:pl-8 w-full scale-95 transform transition duration-500 hover:scale-100 text-left" onClick={toggleSetSecondCard} > {props.user.name} </li> {secondCard && ( <div className="px-4 border-l-4 p-2 bg-accent-0 text-accent-8 pb-4 shadow-lg border-blue"> Hi </div> )} </> ); }; export default function AdminsComponent() { let adminData = [ { name: "asger", index: 1 }, { name: "viggo", index: 2 } ]; return ( <ul> {adminData.map((user) => ( <Card user={user} /> ))} </ul> ); }La desventaja de esta solución es que un componente no puede cambiar de estado en otros componentes, por lo que si desea "cerrar todo" o asegurarse de que solo se muestre una tarjeta a la vez, necesitaría el otro enfoque.
Aquí hay un ejemplo de cómo permitir solo una segunda tarjeta abierta a la vez:
import { useState } from 'react' export default function AdminsComponent() { let adminData = [ { name: "asger", index: 1 }, { name: "viggo", index: 2 } ]; const [openCard, setOpenCard] = useState(0); return ( <ul> {adminData.map((user) => { return ( <> <li key={user.index} className="px-4 my-1 lg:pl-8 w-full scale-95 transform transition duration-500 hover:scale-100 text-left" onClick={() => setOpenCard(openCard == user.index ? 0 : user.index)} > {user.name} </li> {openCard == user.index && ( <div className="px-4 border-l-4 p-2 bg-accent-0 text-accent-8 pb-4 shadow-lg border-blue"> Hi </div> )} </> ); })} </ul> ); }Está utilizando un elemento de estado para alternar la lista completa.
El problema con el enfoque es que, una vez que se cambia el estado, se cambiará para todos los elementos. Un mejor enfoque inicializa el estado como una matriz y, según el índice, sigue mezclando los estados.
import { useState, useEffect } from 'react' export default function AdminsComponent() { const [secondCard, setSecondCard] = useState(Array(adminData.length).fill(false)) const toggleSetSecondCard = (i) => { setSecondCard([...secondCard][i]=!secondCard[i]); } const adminsComponent = adminData.map((user,i) => ( <li key={user.index} className="px-4 my-1 lg:pl-8 w-full scale-95 transform transition duration-500 hover:scale-100 text-left" onClick={e=>toggleSetSecondCard(i)} > // codehere </li> {secondCard && ( <div className="px-4 border-l-4 p-2 bg-accent-0 text-accent-8 pb-4 shadow-lg border-blue"> // ... codehere </div> )} )) return <ul>{adminsComponent}</ul> }