Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

165
Vistas
reaccionar useState solo almacena el último documento

Estoy trabajando en una aplicación web de clonación de Netflix y he almacenado algunos datos en Firestore para hacer una lista de favoritos. Cuando obtuve datos de Firestore e intenté almacenarlos en un estado, ocurrió un error.

Había alrededor de cuatro documentos en Firebase, pero solo obtenía el último cada vez que lo intentaba.

Incluí la clave del mapa e intenté dar la cadena vacía de estado como valor inicial, probé el operador de propagación pero ninguno de ellos funcionó

firestore está funcionando bien, ya que veo esos documentos en la consola

 const [movie, setMovie] = useState([]) useEffect(() => { async function fetchData() { const q = query(collection(db, "movie")); const querySnapshot = await getDocs(q); querySnapshot.forEach((doc) => { setMovie([...movie, doc.data().Details]) console.log(doc.data().Details) console.log(movie) }); } fetchData()
about 4 years ago · Juan Pablo Isaza
3 Respuestas
Responde la pregunta

0

Su función fetchData se cierra sobre movie , lo que significa que solo ve la movie que existía cuando se creó la función (no ha mostrado lo suficiente como para estar seguro, pero supongo que tiene una matriz de dependencias vacía en ese useEffect , por lo que sería ser una movie siempre vacía). Hacer setMovie([...movie, doc.data().Details]) simplemente extiende esa movie vacía y luego agrega el documento final.

En cambio, dos cosas:

  1. Siempre que actualice el estado en función del estado existente, es mejor usar el formulario de devolución de llamada del setter para obtener la versión actualizada del estado que está actualizando.

  2. Reúna los documentos y luego haga una sola llamada de setter.

 const [movies, setMovies] = useState([]) useEffect(() => { async function fetchData() { const q = query(collection(db, "movie")); const querySnapshot = await getDocs(q); setMovies(previousMovies => [ ...previousMovies, ...querySnapshot.map((doc) => doc.data().Details) ]); } fetchData(); }, []); // <== I've assumed this

(Tenga en cuenta que lo he puesto en plural, ya que hay más de una película).

(No uso MongoDB, pero asumí por forEach que querySnapshot es una matriz y, por lo tanto, tiene map . Si no, es bastante fácil crear la matriz, use forEach para push y luego haga setMovies llamar.)


Pero hay otra cosa: debe permitir la posibilidad de que su componente se desmonte antes de que se complete la consulta. Si su getDocs tiene una forma de cancelar su operación, querrá usarla. Por ejemplo, si aceptó una AbortSignal , podría verse así:

 const [movies, setMovies] = useState([]) useEffect(() => { async function fetchData() { const controller = new AbortController(); const { signal } = controller; const q = query(collection(db, "movie")); const querySnapshot = await getDocs(q, signal); if (!signal.aborted) { setMovies(previousMovies => [ ...previousMovies, ...querySnapshot.map((doc) => doc.data().Details) ]); } } fetchData(); return () => { controller.abort(); }; }, []);

Pero si hay algún otro mecanismo de cancelación, úsalo naturalmente.

Si no hay un mecanismo de cancelación, puede usar una bandera para no intentar usar el resultado cuando no se usará para nada, pero eso puede ser excesivo. (React ha dejado de quejarse cuando realiza una actualización de estado después de desmontar el componente, ya que generalmente era algo benigno).

about 4 years ago · Juan Pablo Isaza Denunciar

0

Para empezar, te sugiero que hagas algo como lo siguiente:

 const [movie, setMovie] = useState([]) useEffect(() => { async function fetchData() { const q = query(collection(db, "movie")); const querySnapshot = await getDocs(q); setMovie(querySnapshot.flatMap(elt=>elt.data().Details)); } fetchData()
about 4 years ago · Juan Pablo Isaza Denunciar

0

Es porque actualiza su estado en forEach loop, comienza desde el primer documento hasta el último, al final configura la última película, es por eso que siempre tiene el último documento en su estado.

En primer lugar, no actualice el estado con demasiada frecuencia, ya que crea problemas de rendimiento de la aplicación.

Para solucionarlo (según tu ejemplo):

 let movies=[] querySnapshot.forEach((doc) => { movies([...movies, doc.data().Details]); //or movies.push(doc.data().Details); }); setMovie(movies);
about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda