how to async/await redux-thunk actions?
The Promise approach
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); };}
The async/await approach
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); } }}
Referenced from the Medium post explaining Redux with async/await: https://medium.com/@kkomaz/react-to-async-await-553c43f243e2
Remixing Aspen's answer.
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 }}
This will allow you to specify an array of errors unique to an action.
Another remix for async await redux/thunk. I just find this a bit more maintainable and readable when coding a Thunk
(a function that wraps an expression to delay its evaluation
~ redux-thunk )
actions.js
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 })}
reducers.js
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 }}