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

157
Views
¿Cómo establecer el estado de una matriz de objetos usando useState?

Estoy creando una aplicación de películas en React y estoy usando la API de TMDB para eso. Soy completamente nuevo en componentes funcionales y tengo algunas consultas. Primero busco todos los géneros usando una API, y luego itero los géneros uno por uno y llamo a otra API para buscar 20 películas en ese género.

Los datos finales deberían verse así:

 [{ genre: 'action', movies: [], }, { genre: 'adventure', movies: [], }]

Para que pueda iterar la matriz de objetos anterior y mostrar el género y sus películas correspondientes.

En este momento, estoy atascado con el siguiente código.

 const [movieData, setMovieData] = useState([]); const fetchGenres = async () => { const url = `https://api.themoviedb.org/3/genre/movie/list?api_key=xxx&language=en-US`; try { const res = await fetch(url); const data = await res.json(); setMovieData(data.genres); } catch (err) { console.error(err); } }

Ahora, yendo a las consultas,

  1. En este momento, movieData es una matriz y consta solo de géneros. ¿Cómo agregar películas también y cambiarlas a una matriz de objetos?
  2. ¿Cómo iterar los géneros y configurar las películas correspondientes en movieData?
  3. ¿Alguna otra manera fácil/eficiente de hacer esto?

¡Las soluciones son muy apreciadas!

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

0

En mi opinión, es mejor mantener sus datos por separado. Me refiero a variedad de géneros y variedad de películas. Entonces tendrás:

 const [genres, setGenres] = useState([]); const [movies, setMovies] = useState([]);

luego realiza su llamada asíncrona para buscar géneros y configurarla para que indique:

 const fetchGenres = async () => { const url = `https://baseurl/3/genre/movie/list?api_key=token&language=en-US`; try { const res = await fetch(url); const data = await res.json(); setGenres(data.genres); } catch (err) { console.error(err); } }; React.useEffect(()=>{ fetchGenres(); },[]);

para averiguar que se configuraron los géneros, puede crear un efecto, que se actualizará cada vez que cambien los géneros:

 async function fetchMovies() { let result = []; for (const genre of genres) { const url = `https://baseurl/3/discover/movie?api_key=token&with_genres=${genre.id}`; const res = await fetch(url); const { results } = await res.json(); result = [...result, ...results]; } setMovies(result); } React.useEffect(() => { fetchMovies(); }, [genres]);

y finalmente podemos usar React.useMemo para calcular la matriz de resultados que necesitamos según los géneros y las películas, se recalculará cada vez que cambie uno de los parámetros internos:

 const resultArray = React.useMemo(() => { return genres.map(genre => ({ genre, movies: movies.filter((movie) => movie.genre_ids.includes(genre.id)) })); }, [genres, movies])

Creo que obtendrás una matriz como esta.

 [{ genre: 'action', movies: [], }, { genre: 'adventure', movies: [], }]
about 4 years ago · Juan Pablo Isaza Report

0

Como ya dijiste, primero debes buscar la variedad de géneros. Luego debe iterar sobre esta matriz y crear una lista de promesas para obtener las películas correspondientes. Una vez que se hayan resuelto estas promesas (usando la función Promise.all ), puede actualizar la variable de estado movieData .

 const GENRE_URL = `https://.../genre/movie/list?api_key=xxx&language=en-US`; const MOVIE_URL = `https://.../movie/list?api_key=xxx&language=en-US&genre=`; async function fetchGenres() { try { const genres = await fetch(GENRE_URL).then(res => res.json()); const moviePromises = genres.map(genre => { return fetch(MOVIE_URL + genre) .then(res => res.json()) // build an object containing 2 keys `genre` and `movies` .then(movies => ({genre, movies})); }); return await Promise.all(moviePromises); } catch (err) { console.error(err); throw err; } }

debe adaptar MOVIE_URL a sus necesidades, realmente no sé cuál es la URL real, imagino que necesita pasar el valor del género como un parámetro de ruta o un parámetro de consulta.

ahora puede llamar a esta función en el useEffect para cargar las películas cuando se procesa el componente.

 function App() { const [movieData, setMovieData] = useState([]); useEffect(() => { fetchMoviesGroupByGenre() .then(data => setMovieData(data)) .catch(...); }, []); return ... }

En términos de rendimiento, no mostrará nada antes de que se hayan obtenido todas las películas.

Si es un problema para usted, puede actualizar la variable de estado tan pronto como la API le dé una respuesta.

 async function fetchGenres() { try { const genres = await fetch(GENRE_URL).then(res => res.json()); const moviePromises = genres.map(genre => { return fetch(MOVIE_URL + genre) .then(res => res.json()) .then(movies => { const item = {genre, movies}; setMovieData(prevMovieData => [...prevMovieData, item]); return item; ]); }); return await Promise.all(moviePromises); } catch (err) { console.error(err); throw err; } }
about 4 years ago · Juan Pablo Isaza Report

0

Por lo que entendí lo que quieres hacer es

 setMovieData(prevMovieData => ([ ...prevMovieData, { genre: genreFromApiCall, movies: moviesFromApiCall } ]) )
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!