Estoy empezando a usar React para un proyecto, y realmente estoy luchando para incorporar la funcionalidad async/await en uno de mis componentes.
Tengo una función asíncrona llamada fetchKey que va y obtiene una clave de acceso de una API que estoy sirviendo a través de AWS API Gateway:
const fetchKey = async authProps => { try { const headers = { Authorization: authProps.idToken // using Cognito authorizer }; const response = await axios.post( "https://MY_ENDPOINT.execute-api.us-east-1.amazonaws.com/v1/", API_GATEWAY_POST_PAYLOAD_TEMPLATE, { headers: headers } ); return response.data.access_token; } catch (e) { console.log(`Axios request failed! : ${e}`); return e; } };Estoy usando el tema Material UI de React y quería usar una de sus plantillas de panel. Desafortunadamente, la plantilla de Dashboard usa un componente funcional sin estado:
const Dashboard = props => { const classes = useStyles(); const token = fetchKey(props.auth); console.log(token); return ( ... rest of the functional component's code El resultado de mi console.log(token) es una Promesa, que se esperaba, pero la captura de pantalla en mi navegador Google Chrome es algo contradictoria: ¿está pendiente o se resolvió? 
En segundo lugar, si pruebo en su lugar token.then((data, error)=> console.log(data, error)) , obtengo undefined para ambas variables. Esto parece indicarme que la función aún no se ha completado y, por lo tanto, no ha resuelto ningún valor para data o error . Sin embargo, si trato de colocar un
const Dashboard = async props => { const classes = useStyles(); const token = await fetchKey(props.auth);React se queja poderosamente:
> react-dom.development.js:57 Uncaught Invariant Violation: Objects are > not valid as a React child (found: [object Promise]). If you meant to > render a collection of children, use an array instead. > in Dashboard (at App.js:89) > in Route (at App.js:86) > in Switch (at App.js:80) > in div (at App.js:78) > in Router (created by BrowserRouter) > in BrowserRouter (at App.js:77) > in div (at App.js:76) > in ThemeProvider (at App.js:75) Ahora, seré el primero en decir que no tengo suficiente experiencia para entender qué está pasando con este mensaje de error. Si este fuera un componente tradicional de la clase React, usaría el método this.setState para establecer algún estado, y luego seguiría mi camino feliz. Sin embargo, no tengo esa opción en este componente funcional.
¿Cómo incorporo la lógica async/await en mi componente React funcional?
Editar: Así que solo diré que soy un idiota. El objeto de respuesta real que se devuelve no es response.data.access_token . Era response.data.Item.access_token . ¡Do! Es por eso que el resultado se devolvió como indefinido, aunque se resolvió la promesa real.
Tendrás que asegurarte de dos cosas
useEffect es similar a componentDidMount y componentDidUpdate , por lo que si usa setState aquí, debe restringir la ejecución del código en algún momento cuando se usa como componentDidUpdate , como se muestra a continuación: function Dashboard() { const [token, setToken] = useState(''); useEffect(() => { // You need to restrict it at some point // This is just dummy code and should be replaced by actual if (!token) { getToken(); } }, []); const getToken = async () => { const headers = { Authorization: authProps.idToken // using Cognito authorizer }; const response = await axios.post( "https://MY_ENDPOINT.execute-api.us-east-1.amazonaws.com/v1/", API_GATEWAY_POST_PAYLOAD_TEMPLATE, { headers } ); const data = await response.json(); setToken(data.access_token); }; return ( ... rest of the functional component's code ); }Con React Hooks, ahora puede lograr lo mismo que el componente Class en el componente funcional ahora.
import { useState, useEffect } from 'react'; const Dashboard = props => { const classes = useStyles(); const [token, setToken] = useState(null); useEffect(() => { async function getToken() { const token = await fetchKey(props.auth); setToken(token); } getToken(); }, []) return ( ... rest of the functional component's code // Remember to handle the first render when token is nullTambién eche un vistazo a esto: Uso de Async await en el componente de reacción