Lamento que esta pregunta se haya hecho de manera similar. He leído muchos hilos similares, pero no sé lo suficiente como para aplicarlo a mi pequeño proyecto. ¡Soy muy nuevo en React, así que agradecería cualquier ayuda!
Llegando a eso, estoy haciendo un juego de pokemon en el que alguien puede hacer clic en los botones para filtrar una lista JSON de pokemon. Pueden ir por tipo, debilidad, etc.
Pero estoy un poco confundido al mantener una 'matriz global' si esa es la palabra correcta. Puede ser algo que no entiendo con useState de React.
Aquí está mi código
import React, { useState, useEffect } from "react"; import "./App.css"; import PokemonLibrary from "./data/PokemonList.json"; export default function App() { const [pokemonData, setPokemonData] = React.useState(PokemonLibrary.pokemon); const pokeListCopy = PokemonLibrary.pokemon; const filterTypeOne = () => { //filter type const myFilteredPoke = pokeListCopy.filter((pokeType) => { return pokeType.type.includes("Grass"); }); console.log(myFilteredPoke); // shows array of objects of left over pokemon setPokemonData(myFilteredPoke); }; const filterWeakness = () => { //filter weakness const myFilteredPoke = pokeListCopy.filter((pokeType) => { return pokeType.weaknesses.includes("Ice"); }); setPokemonData(myFilteredPoke); }; return ( <div className="App"> <h1>Pokemon Selector!</h1> <div> <button onClick={filterTypeOne}>Filter Grass</button> <button onClick={filterWeakness}>Weak to Ice</button> </div> {pokemonData && pokemonData.map((poke) => ( <p key={poke.id}> #{poke.num} | {poke.name} | {poke.type[0]} {poke.type[1]} <img src={poke.img} alt="Pokemon Images"></img> </p> ))} </div> ); }Mi pregunta es, ¿cómo mantengo una matriz consistente para estas dos funciones (y más) para extraer los mismos datos? Me gustaría que se pueda filtrar en cualquier orden. Pero actualmente, estos filtran matrices separadas. He jugado mucho con él usando JavaScript normal, pero no puedo entender esto.
Espero que haya sido suficiente información. Por favor, hágamelo saber si esto no tiene sentido! Agradecería cualquier orientación. Gracias.
Se enfrenta a este problema porque intenta establecer el estado de la lista de manera "imperativa", pero React está destinado a usarse más "declarativo". Eso significa que lo que intentas aquí es como:
pero cómo debes usar React es:
Eso puede parecer lo mismo, pero hay una sutil diferencia. React es bueno para cambiar un estado que depende de algún otro estado. Puede decir "pero eso es lo que estoy tratando de hacer, cambiar el estado de la lista", pero luego tiene que contar la historia completa
Esto se vuelve bastante complicado, especialmente comparando contenidos de listas y componentes.
Hay diferentes soluciones a su problema, pero lo que debe hacer es básicamente algo como:
p.ej:
const [pokemonData, setPokemonData] = React.useState(PokemonLibrary.pokemon); const [listState, setListState] = React.useState({ type: '', weekness: '' }); useEffect(() => { let newList = pokemonData; if( listState.type === 'Grass' ){ newList = newList.filter( ... ); } if( listState.weekness === 'Ice' ){ newList = newList.filter( ... ); } setPokemonData(newList); }, listState ); return ( <div> <button onClick={()=>{ setListState({ ...listState, type: 'Grass' }) }}>Filter Grass</button> { pokemonData.map( (poke) => ... ) } </div> );(Este código no es muy elegante y ni siquiera funcionaría, y solo debería ilustrar la idea. De aquí en adelante hay varias formas de implementar el mecanismo de filtrado)