Demystifying Thunk Middleware in Redux

Danny Reina
2 min readSep 24, 2020

--

To begin, we have to understand how Redux behaves. Redux is comprised of reducer/pure functions that represent global state attributes in a React app. Pure functions are defined as given the same input, it will always return the same output. To change state in Redux the reducer accepts an action creator, Redux and action creators are connected by wrapping action creators in a dispatch function provided by Redux, the action creator gives the reducer function a type “CASE CONDITION” and an object. The object represents the new state if the case condition matches between the action creator and reducer, if not, then the reducer returns the initial state ergo reducers are pure functions.

Great, but what happens when we want to get data from other sources such as a public API? In a React-Redux app, we could take advantage of React’s lifecycle component methods and use a fetch function in componentDidMount, right? In reality, we have a very big problem! Take a look at this action creator.

// action creator that fetches data from an APIexport function fetchAstronauts() {const astronauts = fetch('http://api.open-notify.org/astros.json').then(response => response.json())return {type: 'ADD_ASTRONAUTS',astronauts}}

When we hit the fetch function, it creates a Promise object that eventually returns some value that becomes available after the Promise is resolved. We access this Promise object with a .then function that will then allow us to parse the information into JSON and access the data from fetch. So where is the problem?!?!?!?!?!

The problem is that the compiler will continue executing the next line of code after fetch and .then because the action creator function fetchAstronauts is a synchronous function. It will not wait for fetch to resolve itself before executing the next line which would be the return command which constitutes an object that is sent to the reducer to update global state in our Redux store. So how do we solve this? With Thunk :)

// actions/fetchAstronauts.jsexport function fetchAstronauts() {return (dispatch) => {dispatch({ type: 'START_ADDING_ASTRONAUTS_REQUEST' });fetch('http://api.open-notify.org/astros.json').then(response => response.json()).then(astronauts => dispatch({ type: 'ADD_ASTRONAUTS', astronauts }));};}

Thunk is utilized to add an asynchronous nature to action creator functions that employ fetch functions. It does so by allowing the action creators to return a function instead of an object and this function can then be wrapped in a dispatch function which sends the action creator to the store. That is how and why Thunk can be so useful in protecting the integrity of our Redux by telling action creators to wait a moment for the fetch to resolve before sending it to its appropriate reducer function which then updates state accordingly.

--

--

Danny Reina
Danny Reina

No responses yet