⊗jsrxPmATInr 45 of 57 menu

Introduction to thunks in Redux

In the previous chapter, we set up a server, database, and client to communicate. Now we need to build the final bridge that will help our 'synchronous' Redux-based application interact with the asynchronous client we created in the last lesson of the previous chapter to send requests and receive the necessary data in response.

As we remember from the first lessons of the previous section, Redux knows nothing about working with asynchronous logic, and for this we will use thunk middleware. This middleware allows us to work with dispatched actions, use the dispatch and getState store methods in our thunk code, and also help the dispatch method work not only with regular JS objects, but also with entities such as functions and promises.

Typically, a thunk function is called with two arguments, dispatch and getState (if needed), which can be used in the body of the function. It can be used to dispatch regular actions. It can also be dispatched via store.dispatch. An example of such a function is shown below:

const changeColorThunk = (dispatch, getState) => { const colorBefore = getState() console.log(`Old Color: ${colorBefore.color}`) dispatch(changeColor()) const colorAfter = getState() console.log(`New Color: ${colorAfter.color}`) } store.dispatch(changeColorThunk)

Let's now open our product app. The first thing we should get from the server when we launch the app is a list of products. Since thunks are usually written in slice files, we'll open the productsSlice.js file.

The good news is that we don't have to bother with setting up Redux Thunk, as RTK's configureStore function will already do that for us. So let's just add createAsyncThunk to the imports in the file:

import { createSlice, nanoid, createAsyncThunk } from '@reduxjs/toolkit'

Let's also add our client to the import:

import { client } from '../../api/client'

Now, using createAsyncThunk, we'll create our first thunk for receiving products, we'll do this right after declaring the initialState object:

export const fetchProducts = createAsyncThunk()

The first parameter of createAsyncThunk will take a string for the type of action to generate, and the second one will be a callback function for payload, which will return either the data or a promise with an error (see client.js file). In the function code, we call client.get and pass it the path we specified on the server (see the accepted parameters of http.get in server.js):

export const fetchProducts = createAsyncThunk( 'products/fetchProducts', async () => { const response = await client.get('/fakeServer/products') return response.data } )

Open your students app. Open the studentsSlice.js file in it. Import the createAsyncThunk function to create the thunk, and the client function to send API requests to the server.

Immediately after declaring the initialState object, use createAsyncThunk to create a fetchStudents thunk to get the list of students, which will send a GET request to /fakeServer/students specified in your server.js file and return response.data as shown in the tutorial materials. As the first parameter to createAsyncThunk, specify the string students/fetchStudents for the action type.

enru