Supongamos que busco datos de una API que devuelve una matriz de objetos, cada uno de los cuales representa una película, similar a esto:
[{ "name": "The Matrix", "img": "http://...", "description": "Lorem ipsum...", "first_aired": "1999" }, ...]
lo que quiero es:
Pegar debajo de lo que he implementado hasta ahora, pero me pregunto si hay una forma más elegante de hacerlo. Es decir, en lugar del operador ternario, ¿hay alguna manera de simplemente tener <CardList items={movies} /> y pasar TODAS las películas o películas FILTRADAS (un subconjunto), como accesorios, dependiendo de si el botón está activado o no?
Intenté hacerlo dentro del controlador handleToggle con el tipo de lógica if (toggle) {} que funcionó hasta el punto de que hacer clic en el botón filtraría y, por lo tanto, mostraría todas las películas emitidas antes de 2013, pero hacer clic nuevamente no actualizaría la variable de estado de las movies . Vuelva a TODAS las películas y reprodúzcalas según corresponda.
Dentro del componente CardList también hay un componente Card , si eso ayuda. Y dentro del componente CardList , estoy usando la función de map para iterar sobre los accesorios de movies / películas filteredMovies para representar los componentes de la Card .
function App() { const [movies, setMovies] = useState([]); const [toggle, setToggle] = useState(true); useEffect(() => { const getData = fetch('https://api.com/movies') .then(data => data.json()) .then(items => setMovies(items)) }, []) const filteredMovies = movies.filter(item => item.first_aired <= 2013); const handleToggle = () => setToggle(!toggle) return ( <div className="App"> <button onClick={handleToggle}>{toggle ? "Only show movies aired ≤ 2013" : "Show all movies"}</button> {toggle ? <CardList items={movies} /> : <CardList items={filteredMovies} />} </div> ); } export default App; <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>function App() { const [movies, setMovies] = useState([]); const [moviesBackup, setMoviesBackup] = useState([]); const [toggle, setToggle] = useState(true); useEffect(() => { const getData = fetch('https://api.com/movies') .then(data => data.json()) .then(items => {setMovies(items), setMoviesBackup(items)}) }, []) const filteredMovies = movies.filter(item => item.first_aired <= 2013); const handleToggle = () => { setToggle(!toggle); //Permit this condition if i am wrong according to button state if(toggle === true){ setMovies(filteredMovies) }else{ setMovies(moviesBackup) } } return ( <div className="App"> <button onClick={handleToggle}>{toggle ? "Only show movies aired ≤ 2013" : "Show all movies"}</button> <CardList items={movies} />} </div> ); } export default App;De hecho, estás derrotando la idea de Reaccionar aquí 😛. Reaccionar sería reemplazar
{toggle ? <CardList items={movies} /> : <CardList items={filteredMovies} />} con solo <CardList items={filteredMovies} /> donde filteredMovies es un gancho y luego simplemente mute filteredMovies con setFiteredMovies() . React actualizará la interfaz de usuario automáticamente.