Blog>
Snippets

Implementing Thunks with the Latest Redux API

Demonstrate the implementation of thunks in Redux v5.0.0, while handling asynchronous operations.
import { configureStore } from '@reduxjs/toolkit';
import rootReducer from './reducers';
import thunk from 'redux-thunk';

const store = configureStore({
  reducer: rootReducer,
  middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(thunk),
});

export default store;
This code snippet sets up a Redux store with the latest Redux Toolkit API. It imports the configureStore function and redux-thunk middleware. The rootReducer combines all the reducers for the app, and redux-thunk allows for asynchronous actions. The default middleware is extended with thunk to handle asynchronous operations.
import { createAction, createReducer } from '@reduxjs/toolkit';

// Define an async action creator using thunk
export const fetchData = () => async (dispatch) => {
  try {
    const response = await fetch('https://api.example.com/data');
    const data = await response.json();
    dispatch(fetchDataSuccess(data));
  } catch (error) {
    dispatch(fetchDataFailed(error.toString()));
  }
};

// Action creators for success and failure
export const fetchDataSuccess = createAction('data/fetchDataSuccess');
export const fetchDataFailed = createAction('data/fetchDataFailed');
Here we define an asynchronous action creator using redux-thunk. The action creator fetchData is a thunk that dispatches either fetchDataSuccess or fetchDataFailed depending on the result of the fetch request. The createAction function from Redux Toolkit is used to create corresponding actions for success and failure of data fetching.
const initialState = {
  data: null,
  loading: false,
  error: null,
};

const dataReducer = createReducer(initialState, (builder) => {
  builder
    .addCase(fetchDataSuccess, (state, action) => {
      state.data = action.payload;
      state.loading = false;
      state.error = null;
    })
    .addCase(fetchDataFailed, (state, action) => {
      state.error = action.payload;
      state.loading = false;
    })
    // Handle more actions here
});

export default dataReducer;
The dataReducer is created using the createReducer function from Redux Toolkit. It handles actions dispatched by fetchData, updating the state with data, error information, and loading state accordingly. The initialState provides the default state shape, with null values for data and error and a loading flag.
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <script src="store.js"></script>
  <script src="reducers.js"></script>
  <title>Redux Thunks Example</title>
</head>
<body>
  <div id="app">
    <!-- Your app content here -->
  </div>
  <script src="index.js"></script>
</body>
</html>
A simple HTML template to serve the application. It includes store.js and reducers.js, which contain our Redux store and reducers. The index.js will be the entry point for our application where we will manage the Redux-related operations.
body {
  font-family: Arial, sans-serif;
}

/* Additional CSS can be added here to style the application */
In this code snippet, we add basic CSS for the body of the document using Arial font. More styling can be added to customize the appearance of the application.