Un novato de React aquí. Una cosa muy simple que parece que no puedo hacer bien.
Quiero cambiar la clase en el elemento seleccionado de mi mapa, no todos.
Por ejemplo, si hago clic en un elemento con una identificación de 1, debería tener una clase de 'color activo'. Si luego hago clic en el elemento con una identificación de 2, ese elemento debería tomar la clase 'color activo' y la identificación 1 ya no debería tener esta clase.
He intentado muchas soluciones diferentes, pero parece que no puedo hacerlo bien. No parece que me guste usar el gancho en mi función de controlador aquí y devuelve un error: TypeError: setActive is not a function .
¡Cualquier idea u otra solución será muy apreciada!
const ListItems = () => { const { isActive, setActive} = useState(false) const { item, dispatch } = useContext(AppContext); const handler = (event) => { dispatch({ type: 'SET_ITEM', payload: event.currentTarget.dataset.index, }); setActive(!isActive); }; return ( <div className="container"> <h2 className="smallheader">Please choose one</h2> <div className="flex flex-center"> {ITEMS.map((item) => <div className={isActive ? 'active-color' : 'card'} data-index={item.value} key={item.id} onClick={handler}> <span className="card-header">{item.name}</span> <span className="card-description">{item.description}</span> </div> )} </div> </div> ) }; export default ListItems;Su primer problema es que useState() devuelve una matriz, no un objeto. Eso significa que cuando desestructura isActive y setIsActive necesita usar la destrucción de matriz [] :
const [isActive, setActive] = useState(false); Dependiendo de cómo esté configurado su AppContext , es posible que también deba usar la desestructuración de la matriz para el artículo y el envío. Su próximo problema es que el estado anterior solo almacena un valor booleano. Cuando es verdadero, será true para cada valor que represente durante el mapeo. Lo que significa que cuando activo se establece en verdadero, a todos los elementos se les aplicará la clase activa. Para ayudar a administrar esto, puede cambiar su valor de estado para mantener la identificación del elemento que está activo. Luego, en su función de devolución de llamada de mapeo, verifique si la identificación del elemento actual coincide con la identificación almacenada en su estado y, si es así, use la clase active-color ; de lo contrario, use la clase de card .
const [activeItem, setActiveItem] = useState(-1); const handler = (itemId) => { dispatch({ // you may want to conditionally call this, but I'm basing it off your current logic type: 'SET_ITEM', payload: itemId, }); setActiveItem(currentItem => currentItem === -1 ? itemId : -1); // toggle between -1 and itemPressed to make active state toggleable }; return ( <div className="container"> <h2 className="smallheader">Please choose one</h2> <div className="flex flex-center"> {ITEMS.map((item) => <div className={activeItem === item.id ? 'active-color' : 'card'} key={item.id} onClick={() => handler(item.id)}> ...La desestructuración de la matriz requiere corchetes:
En vez de:
const { isActive, setActive} = useState(false) const { item, dispatch } = useContext(AppContext);Escribe:
const [ isActive, setActive] = useState(false) const [ item, dispatch ] = useContext(AppContext);