Async Redux Actions

The Redux docs provide an excellent introduction on how to write asynchronous operations in the context of Redux.

We can dispatch async actions like this:

// ShowImages.jsx
import React from 'react'
import { useDispatch } from 'react-redux'
function ShowImages () {
// This will make `dispatch` available to the component.
const dispatch = useDispatch()
return (
// dispatching the findImages() action
<button onClick={() => dispatch(findImages('wombats'))}>
Show wombat pics
</button>
)
}
export default ShowImages

Here findImages is just an action creator, but a slightly fancy one. Instead of returning an object with a type property like our typical action creators, it returns a function. Let's assume we're using Superagent to make the API call:

// actions.js
function findImages (searchterm) {
// returning a function instead of an object!
return (dispatch) => {
// dispatching as many normal actions as we like
// updating our store state throughout the process of our async API call
dispatch(requestImages())
request
.get(`https://api.instagram.com/v1/tags/search?q=${searchterm}`)
.then((res) => {
// dispatching again here
dispatch(receiveImages(res.body)))
})
.catch((err) => {
// or here if there's an error
dispatch(retrievalError(err))
})
}
}
function requestImages () {
// maybe used to set a loading indicator
return {
type: 'REQUEST_IMAGES'
}
}
function receiveImages (images) {
// stop the loading indicator and show the images
return {
type: 'RECEIVE_IMAGES',
images
}
}
function retrievalError (err) {
// stop the loading indicator and show the error message
return {
type: 'RETRIEVAL_ERROR',
errMessage: err.message
}
}

Some key ideas from this:

  • We track progress of async calls using normal actions.
  • We can call dispatch more than once during the process.
    • For example, we could display a loading spinner when the REQUEST_IMAGES action is dispatched, and then remove it once the RECEIVE_IMAGES action is dispatched.
  • This is made possible by the thunk Redux middleware. If it sees that the action dispatched is a function (the findImages action creator returns a function), thunk calls that function, passing in dispatch.
  • Normal actions (objects) are passed straight through to the store, which will then call our reducers (as we've been doing all week.)