acción.js
export function getLoginStatus() { return async(dispatch) => { let token = await getOAuthToken(); let success = await verifyToken(token); if (success == true) { dispatch(loginStatus(success)); } else { console.log("Success: False"); console.log("Token mismatch"); } return success; } }componente.js
componentDidMount() { this.props.dispatch(splashAction.getLoginStatus()) .then((success) => { if (success == true) { Actions.counter() } else { console.log("Login not successfull"); } }); }Sin embargo, cuando escribo el código de component.js con async/await como se muestra a continuación, aparece este error:
Possible Unhandled Promise Rejection (id: 0): undefined is not a function (evaluating 'this.props.dispatch(splashAction.getLoginStatus())')
componente.js
async componentDidMount() { let success = await this.props.dispatch(splashAction.getLoginStatus()); if (success == true) { Actions.counter() } else { console.log("Login not successfull"); } }¿Cómo espero un getLoginStatus() y luego ejecuto el resto de las declaraciones? Todo funciona bastante bien cuando se usa .then(). Dudo que falte algo en mi implementación async/await. tratando de averiguar eso.
El enfoque de la promesa
export default function createUser(params) { const request = axios.post('http://www...', params); return (dispatch) => { function onSuccess(success) { dispatch({ type: CREATE_USER, payload: success }); return success; } function onError(error) { dispatch({ type: ERROR_GENERATED, error }); return error; } request.then(success => onSuccess, error => onError); }; }El enfoque async/await
export default function createUser(params) { return async dispatch => { function onSuccess(success) { dispatch({ type: CREATE_USER, payload: success }); return success; } function onError(error) { dispatch({ type: ERROR_GENERATED, error }); return error; } try { const success = await axios.post('http://www...', params); return onSuccess(success); } catch (error) { return onError(error); } } }Referencia de la publicación de Medium que explica Redux con async/await: https://medium.com/@kkomaz/react-to-async-await-553c43f243e2
Remezclando la respuesta de Aspen .
import axios from 'axios' import * as types from './types' export function fetchUsers () { return async dispatch => { try { const users = await axios .get(`https://jsonplaceholder.typicode.com/users`) .then(res => res.data) dispatch({ type: types.FETCH_USERS, payload: users, }) } catch (err) { dispatch({ type: types.UPDATE_ERRORS, payload: [ { code: 735, message: err.message, }, ], }) } } } import * as types from '../actions/types' const initialErrorsState = [] export default (state = initialErrorsState, { type, payload }) => { switch (type) { case types.UPDATE_ERRORS: return payload.map(error => { return { code: error.code, message: error.message, } }) default: return state } }Esto le permitirá especificar una serie de errores exclusivos de una acción.
Otro remix para async espera redux/thunk. Simplemente encuentro esto un poco más mantenible y legible cuando codifico un Thunk ( a function that wraps an expression to delay its evaluation ~ redux-thunk )
import axios from 'axios' export const FETCHING_DATA = 'FETCHING_DATA' export const SET_SOME_DATA = 'SET_SOME_DATA' export const myAction = url => { return dispatch => { dispatch({ type: FETCHING_DATA, fetching: true }) getSomeAsyncData(dispatch, url) } } async function getSomeAsyncData(dispatch, url) { try { const data = await axios.get(url).then(res => res.data) dispatch({ type: SET_SOME_DATA, data: data }) } catch (err) { dispatch({ type: SET_SOME_DATA, data: null }) } dispatch({ type: FETCHING_DATA, fetching: false }) } import { FETCHING_DATA, SET_SOME_DATA } from './actions' export const fetching = (state = null, action) => { switch (action.type) { case FETCHING_DATA: return action.fetching default: return state } } export const data = (state = null, action) => { switch (action.type) { case SET_SOME_DATA: return action.data default: return state } }