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

117
Views
Mezcle useEffect y onValue de Firebase

Cuando trabajo con Firebase y React , para obtener datos basados en cambios de estado o en cambios internos de la base de datos (de otro usuario, por ejemplo), a menudo confío en fragmentos de código como este:

 useEffect(() => { const getGamesInSelectedGroup = () => { if (!state.currentGroup) { return } const db = getDatabase(); const resp = ref(db, `/games/${state.currentGroup.name}`); onValue(resp, (snap) => { if (snap.exists()) { const data = snap.val() const games = Object.keys(data).map(k => ({id: k, group: state.currentGroup.name, ...data[k]})) setState((prev) => ({ ...prev, games: games, isLoaded: true, })); return } setState((prev) => ({ ...prev, games: null, isLoaded: true, })); toast.warning("no data for " + state.currentGroup.name) }) } getGamesInSelectedGroup(); }, [state.currentGroup])

Sin embargo, me pregunto si, cada vez que cambia state.currentGroup , se crea un nuevo oyente para /games/${state.currentGroup.name} . Si es así, ¿hay algún medio para cancelar la suscripción al oyente anterior antes de crear uno nuevo?

He pensado en reemplazar onValue por una llamada de get , todavía condicionada por state.currentGroup y usando onValue fuera de useEffect para reflejar el cambio "interno" de la base de datos.

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

0

En lugar de anidar todo en su función getGamesInSelectedGroup (que es el patrón que usaría para las API basadas en Promise), simplemente llámelo en el cuerpo de useEffect para simplificar la administración del oyente:

 useEffect(() => { if (!state.currentGroup) { return } const db = getDatabase(); const resp = ref(db, `/games/${state.currentGroup.name}`); return onValue(resp, (snap) => { // <--- return the unsubscriber! if (snap.exists()) { const data = snap.val() const games = Object.keys(data) .map(k => ({ id: k, group: state.currentGroup.name, ...data[k] })); setState((prev) => ({ ...prev, games, // you can use this instead of "games: games" isLoaded: true, })); return } setState((prev) => ({ ...prev, games: null, isLoaded: true, })); toast.warning("no data for " + state.currentGroup.name) }); }, [state.currentGroup])

También recomendaría usar una función de "instantánea a la matriz de niños" en lugar de usar Object.keys(snapshot.val()) para mantener el orden de clasificación de la consulta (se ignoraría usando el código tal como está). Desafortunadamente, en el momento de escribir este artículo, todavía no existe un equivalente de QuerySnapshot#docs de Firestore para RTDB. Pero es bastante fácil hacer el nuestro:

 // returns array of DataSnapshot objects under this DataSnapshot // put this outside of your component, like in a common function library file const getSnapshotChildren = (snapshot) => { const children = []; // note: the curly braces on the next line are important! If the // callback returns a truthy value, forEach will stop iterating snapshot.forEach(child => { children.push(child) }) return children; } useEffect(() => { if (!state.currentGroup) { return } const db = getDatabase(); const resp = ref(db, `/games/${state.currentGroup.name}`); return onValue(resp, (snap) => { // <--- return the unsubscriber! if (snap.exists()) { const games = getSnapshotChildren(snap) .map(child => ({ id: child.key, group: state.currentGroup.name, ...child.val() })); setState((prev) => ({ ...prev, games, // you can use this instead of "games: games" isLoaded: true, })); return } setState((prev) => ({ ...prev, games: null, isLoaded: true, })); toast.warning("no data for " + state.currentGroup.name) }); }, [state.currentGroup])
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!