How to Implement Thunk in Your React-Redux Application

Lauren Yu
3 min readApr 23, 2020

Along with my other blog on the basic setup of Redux, Redux with Hooks: Basic Setup, I thought it would be helpful to write out the steps to adding Thunk to your React-Redux application. Feel free to check out the sample code!

Step 1: Run npm install redux-thunk.

What is Thunk? Basically, it’s middleware that checks to see if an action is returning a function instead of the normal JavaScript plain object. If that’s the case, it will catch the action before it reaches the reducer and invoke the function (which often returns another action to be passed on to the reducer). If the original action is just a normal plain JavaScript object, Thunk lets it pass on to the reducer uninterrupted.

Step 2: In store.js, import thunk from 'redux-thunk'. In addition to createStore, import applyMiddleware from 'redux'. Then, pass applyMiddleware(thunk) through as your second argument in place of your Dev tools middleware.

Step 2A(optional): Unfortunately, with the above code, we lose out on using our Chrome developer tools. If you’d like to use Thunk AND dev tools, you need to import {compose} from 'redux'. Then, create composeEnhancers

const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;

(copied directly from the documentation) and pass that in as the second argument with the argument applyMiddleware(thunk). (Wow that’s a mouthful!)

To see Thunk in action, we’re creating a VERY basic application that fetches a random joke as soon as the app is mounted from a free api: https://official-joke-api.appspot.com/random_joke. To follow along, simply do the Redux file setup portion (steps #1–6) of Redux with Hooks: Basic Setup before moving on. If you’d prefer to see the full code, you can pull down the repo.

Step 3: First, we need to write the function in actions.js that will deal with the fetch call.

For right now, we can just do a console.log to see if we’re able to retrieve a joke. Don’t forget to export your function!

Step 4: Next, we need to import {fetchingJoke} from './redux/actions', import {useEffect} from 'react' and import {useDispatch} from 'react-redux'into App.js. Create a useEffect that, on load of the page, dispatches the fetchingJoke action.

And voilà!

Step 5: In order to handle the data once we get it, we’ll want to create another function called fetchedJoke in actions.js. Then, we’ll need to update fetchingJoke to call fetchedJoke once it’s finished. Notice that we now have to pass dispatch into the return function of our fetchingJoke function.
Note: Both dispatch and the current state, getState can be passed in as arguments. Check out the docs!

Quick recap: Without Thunk, Redux is looking to pass only plain JavaScript objects to the reducer. Our middleware, Thunk, is watching for actions that return functions; when it sees a function (fetchingJoke), it executes said function, which often returns a plain JavaScript (fetchedJoke), which is then dispatched and updates the reducer.

Step 6: In reducer.js, add case "FETCHED_JOKE": in the jokeReducer switch statement. Since the payload is just our joke object, and it’s the first time the state will update since our app is rendered, we can simply return action.payload.

And that’s it! On load of the page, the state in your Redux store will update to…

We’re finished with the Thunk portion of our app, but just to finish up the Basic Joke Application, you can access the joke portion of state with useSelector to App.jsand then create a VERY basic UI that allows users to conditionally render the punchline.

You can even call the fetchingJoke action again whenever a user would like to get a new joke.

--

--

Lauren Yu

Software engineer/full-stack developer and founding member of the Breaking Winds Bassoon Quartet.