Tengo una aplicación React creada con la plantilla Minimal y estoy tratando de seguir uno de sus tutoriales para crear una porción de Redux que alimente algunos datos a un componente personalizado. Los datos en sí se recopilan de Firebase. A continuación se muestra mi código:
firebase.js - ayudante
export function getDocuments(col) { const colRef = collection(db, col); const q = query(colRef, where('uid', '==', auth.currentUser.uid)); getDocs(q).then((snap) => { const data = snap.docs.map((d) => ({ id: d.id, ...d.data() })); return data; }); // return [1,2,3] }product.js - Rebanada de Redux
export function getProducts() { return async (dispatch) => { dispatch(slice.actions.startLoading()); try { const products = await getDocuments('products'); dispatch(slice.actions.getProductsSuccess(products)); } catch (error) { dispatch(slice.actions.hasError(error)); } }; }ProductList.js - componente
const dispatch = useDispatch(); const { products } = useSelector((state) => state.client); useEffect(() => { dispatch(getProducts()); }, [dispatch]); useEffect(() => { if (products.length) { // setTableData(products); } }, [products]); Si consuelo data de registro en la función auxiliar ( firebase.js ), obtengo los valores que espero, una vez que se resuelve/cumple la promesa. Sin embargo, si consola. registro clients en el segmento product.js o más tarde en el componente, obtengo undefined . Supongo que mi problema es no poder entender cómo async + await + useEffect funcionan juntos para solucionar esto. Mi suposición es que estoy tratando de acceder al valor antes de que se resuelva la promesa y, por lo tanto, antes de que la función auxiliar lo devuelva. Lo confirmé al devolver una matriz simple [1, 2, 3] en mi función auxiliar como prueba.
Creo que me estoy perdiendo algo fundamental aquí (no tengo mucha experiencia con React y JS en general y sigo aprendiendo cosas sobre la marcha). ¿Alguien puede ayudarme a entender qué estoy haciendo mal?
¡Gracias!
Con await puede esperar el cumplimiento o el rechazo de una promesa, pero su función getDocuments no devuelve una promesa. Cambie la última línea de la función a lo siguiente:
return getDocs(q).then((snap) => { const data = snap.docs.map((d) => ({ id: d.id, ...d.data() })); return data; });Async y Await no son diferentes en React que en JavaScript simple: cuando se aplica la palabra clave await, suspende el método de llamada y devuelve el control a la persona que llama hasta que se completa la tarea esperada. await solo se puede usar dentro de un método asíncrono
useEffect() : Al usar este Hook, le dice a React que su componente necesita hacer algo después de renderizar. Esta función se ejecutará cada vez que se vuelva a renderizar el componente.