Quiero insertar datos asincrónicos de Firestore en elementos de React. Tengo un par de funciones que manejan el flujo.
getEvents() es una función asíncrona que devuelve una matriz de objetos que son mis datos de Firestore.
const getEvents = async() => { try { const data = query(collection(db, id)); const events = []; const snapshot = await getDocs(data); snapshot.forEach((doc) => events.push(doc.data())); return events; } catch(error) { console.error(error); } } Se hace referencia a esta función en receiveEvents() donde tomo los datos devueltos y los coloco en una matriz global para usarlos en el DOM.
let userEvents = []; const receiveEvents = () => { getEvents() .then(result => userEvents = result) .catch(error => console.error(error)); Esta función se usa en displayEvents() para pegar los datos devueltos en el elemento deseado. La función se llama al hacer clic en un botón.
const displayEvents = () => { try { const btnContainer = document.querySelector(".btn-container"); ReactDOM.render(<AppNavigation />, btnContainer); receiveEvents().then(() => { return userEvents }); } catch(error) { console.error(error); } } Recibo un error index.js:1 TypeError: Cannot read properties of undefined (reading 'then') @ displayEvents .
Estas funciones utilizan el ID de usuario registrado para acceder al directorio correcto en la base de datos. Recupero la ID en una función determinada declarada en la parte superior del archivo.
let id = null; const getUserId = () => { try { console.log("getUserId()"); return auth.currentUser.uid; } catch(error) { console.error(error); } } El <AppNavigation/> devuelve un div , a saber:
<div className="arrow-navigation-container"> <button className="arrow-btn"><span className="icon arrow">arrow_back</span></button> <button className="arrow-btn"><span className="icon arrow">arrow_forward</span></button> </div> ¿Qué puedo hacer para obtener los datos asincrónicos en la matriz de userEvents de usuario, para poder mostrárselos al usuario cuando lo solicite?
Yo usaría ganchos para esto personalmente:
Ejemplos de cómo usar esos ganchos: https://reactjs.org/docs/hooks-reference.html#usestate
El useState entraría en el mismo componente que el proveedor de useContext, por lo general, en las aplicaciones de ejemplo, está en el componente. El componente que necesita los datos debe ser un elemento secundario de Context.Provider, pero no es necesario que sea un elemento secundario directo.
useEffect también va al mismo componente, y con las dependencias puede decidir si desea obtener los datos solo una vez o, por ejemplo, cuando cambia esa ID.