What are "Thunk" and `createAsyncThunk` in Redux Toolkit?
Ali Bahaari
Posted on March 1, 2022
What Is Thunk In Redux?:
Thunk is used for fetching data from a API and storing response in Redux states which shortens and increases code clean-up.
What did you use to fetch data?
First, by using useEffect hook and in componentDidMount lifecycle, you would have fetched data from an API. What about storing in Redux? You would have used useDispatch hook for storing and then using useSelector for getting the data.
OK? Now, this operations are assigned to Thunk and you don't need to crowd every components in which you use the data you've called an API.
After that, you should check the results for statuses which can be fulfilled, rejected and pending which can be done more easily by using Thunk.
And remember this is a quote from Redux Toolkit documentations:
This abstracts the standard recommended approach for handling async request lifecycles.
Thus, code is cleaner, more standard and more flexible in writing.
Example In Usage
Consider I have a slice called usersSlice.js
. createAsyncThunk
will be used and created as shown below. Assume we want to fetch users list from an API:
import { createAsyncThunk } from '@reduxjs/toolkit';
export const getUsers = createAsyncThunk(
'usersSlice/getUsers',
async () => {
return await fetch('http://localhost:4000').
then(res => res.json());
}
);
const initialState = {
status: null,
data: []
}
const usersSlice = createSlice({
name: 'usersSlice',
initialState,
extraReducers: {
[getUsers.pending] = (state) => {
state.status = 'Pending';
},
[getUsers.fulfilled] = (state, action) => {
state.status = 'Fulfilled';
state.data = action.payload;
},
[getUsers.rejected] = (state) => {
state.status = 'Rejected';
}
}
export default usersSlice.reducer;
First you create a variable called getUsers
which is assigned to createAsyncThunk
(notice export keyword before declaring the variable). createAsyncThunk
has 2 arguments. The first one is a string for specifying the Thunk name and the second one is a async function which will return a promise.
Then you create a slice by using createSlice
. In extraReducers
(notice reducers
property is different) you specify 3 probable states of the promise which are pending
, fulfilled
and rejected
. You decide what should Redux do in these 3 different states of the API.
- Pending means API manipulation is being continued.
- Fulfilled means response was got from API.
- Rejected means API call was failure.
After that, you declare the reducer you've created in configureStore
:
import { configureStore } from '@reduxjs/toolkit';
import usersSlice from './slices/usersSlice';
export const store = configureStore({
reducer: {
usersSlice,
...
}
});
Then, create a component called UsersListComponent.js
and then, you'll do as this:
import { useEffect } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { getUsers } from './store/slices/usersSlice';
...
const dispatch = useDispatch();
const usersData = useSelector(state => state.usersSlice.data);
const usersDataStatus = useSelector(state => state.usersSlice.status);
useEffect(() => {
dispatch(getUsers());
}, []);
First you should dispatch the async function you've created by using createAsyncThunk
. All operations will be done by Redux and BOOM! Everything is ready and you can use useSelector
hook to get data and use it as you like:
return (
<>
{
usersData.map(userData => (
<div>
<span>{userData.id}</span>
<span>{userData.firstName}</span>
<span>{userData.lastName}</span>
</div>
))
}
</>
);
Also you can use status
state for checking the status of the API:
return (
<>
{
usersDataStatus === 'Pending' ? <span>Pending</span> :
usersDataStatus === 'Fulfilled' ? <span>Fulfilled</span> :
usersDataStatus === 'Rejected' ? <span>Rejected</span> :
''
}
{
usersData.map(userData => (
<div>
<span>{userData.id}</span>
<span>{userData.firstName}</span>
<span>{userData.lastName}</span>
</div>
))
}
</>
);
Everything works as before but cleaner, more standard and more flexible.
Congratulation! You've been learning how to use Thunk and createAsyncThunk
in Redux Toolkit.
Posted on March 1, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.