How to Setup Redux In React : A Step By Step Guide

Are you looking to your Redux toolkit setup in a React TypeScript project? Look no further! In this comprehensive guide, we'll walk you through the process of integrating Redux Toolkit, a powerful package that simplifies Redux boilerplate and enhances developer productivity.

Setting up a React TypeScript Clean project with Redux Toolkit involves a few steps. Redux Toolkit simplifies the Redux setup process by providing utilities to reduce boilerplate code. Here's a step-by-step guide to setting up a basic React TypeScript project with Redux Toolkit


By the end of this tutorial, you'll be equipped with the knowledge to effortlessly manage your state in a more elegant and understandable manner.below I will share source code you can check ✅


File Structure : 






Step 1: Crate React App with TypeScript


npx create-react-app my-app --template typescript



Step 2: Install Redux Toolkit

Let's kick off by installing Redux Toolkit into your project. Open your terminal and navigate to your project directory. Then, run the following command:


npm install @reduxjs/toolkit react-redux @types/react-redux



Step 3:  Create a Redux Store:

Create a file to configure your Redux store. In this example



import { configureStore } from "@reduxjs/toolkit";
import reducer from "./reducer";
import api from "./middleware/api";

const configureAppStore = () => configureStore({
    reducer,
    middleware: (getDefaultMiddleware) => getDefaultMiddleware({
        serializableCheck: false,
    }).concat(api),
});

export default configureAppStore;


Step 4: Define Reducers:

You need to define reducers for managing different slices of your application state. Each reducer corresponds to a slice of the overall state.Example reducers.ts:


import { combineReducers } from "redux";
import { homeSlice } from "./home";
export default combineReducers({
     homeData: homeSlice.reducer,
})




Step 5: Create Slice Reducers:

Use createSlice from Redux Toolkit to define slice reducers. These slice reducers handle actions and state for specific parts of your application.

Example home.ts:




import { createSlice } from "@reduxjs/toolkit";
import { apiCallBegan } from "./api";
import BASE_URL from "../config/host";

export const homeSlice = createSlice({
  name: "homeData",
  initialState: {
    loading: false,
    homeData: [],
  },
  reducers: {
    Requested: (state, action) => {
      
      state.loading = true;
    },
    Failed: (state, action) => {
      state.loading = false;
    },
    Received: (state, action) => {
      state.loading = false;
      //console.log(action.payload.products)
      state.homeData = action.payload.products;
    },
  },
});

export const { Received, Requested, Failed } = homeSlice.actions;
//console.log(body);

export const fetchHomeData = () =>
  apiCallBegan({
    url: "/products",
    method: "get",
    data: {},
    baseUrl: BASE_URL,
    onSuccess: 'homeData/Received',
    onStart: 'homeData/Requested',
    onError: 'homeData/Failed',
  });



Step 6: Create Middleware

First, let's create a middleware function. for example api.ts under middleware folder




import axios from "axios";
import * as actions from '../api';
import { Middleware } from "@reduxjs/toolkit";
import { ThunkDispatch, AnyAction } from "@reduxjs/toolkit";
//import {ADMIN_URl} from '../../config/host';

const api: Middleware<{}, unknown, ThunkDispatch> = ({dispatch}) => next => async (action:any) => {
    let token =    await localStorage.getItem('accessToken');
    // console.log(action.payload, `type: ${action.type}`);
    // console.log(actions.apiCallBegan.type);
    // console.log('****break***');
    if(action.type !== actions.apiCallBegan.type){
        return next(action)
    }

   // console.log(action.payload,'action.payload')
    const {url, method, data, onStart, onSuccess, onError, baseUrl} = action.payload;
    if(onStart){
        dispatch({
            type: onStart
        })
    }
    next(action);
 
    try{
        let response:any;
        if(token){
             response = await axios.request({
                baseURL: baseUrl,
                url,
                method,
                data,
                headers: {
                    Authorization: `Bearer ${token}`,
                   //'content-type': 'multipart/form-data',
                   // 'content-type': 'application/x-www-form-urlencoded' 
                   }
            });
        }else{
             response = await axios.request({
                baseURL: baseUrl,
                url,
                method,
                data
            });
        }
       

        dispatch(actions.apiCallSuccess(response.data));
        //console.log(response.data);
        if(onSuccess){
         // console.log(response.data);
            dispatch({
                type: onSuccess,
                payload: response.data
            })
            
        }

    }catch(err:any){
    // console.log(err.response.data,'err.response')
       dispatch(actions.apiCallFailed(err.response.data));
        if(onError){
            dispatch({
                type: onError,
                payload: err.response.data
            })
        }
    }
}

export default api


Step 7 : Define action creators for API calls



import { createAction } from "@reduxjs/toolkit";
export const apiCallBegan = createAction('api/callBegan');
export const apiCallSuccess = createAction('api/callSuccess');
export const apiCallFailed = createAction('api/callFailed');


Step 8 : Connect Redux Store to React

In your main component or at the root of your application, wrap your app with the Redux Provider component and pass your Redux store as a prop.
Example index.tsx:


import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import configureAppStore from "./store/configureStore";
import { Provider } from "react-redux";

const root = ReactDOM.createRoot(
  document.getElementById('root') as HTMLElement
);

const store = configureAppStore();

root.render(
  
      
  
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();


Step 9 : Use Redux State in Components

Finally, you can use Redux state and dispatch actions in your React components using the useSelector and useDispatch hooks provided by react-redux.

Example App.tsx:

import React, { useEffect } from 'react';
import logo from './logo.svg';
import './App.css';
import { useDispatch, useSelector } from "react-redux";
import { fetchHomeData } from "./store/home";

function App() {
   const dispatch = useDispatch()
  useEffect(()=>{
    dispatch(fetchHomeData())
  },[dispatch])

  const homeData = useSelector(
    (state: any) => state.homeData.homeData
  );

  console.log(homeData,'homeData');
  return (
  view
  );
}

export default App;



By following these steps, you can simplify your Redux setup in a React TypeScript project using Redux Toolkit, reducing boilerplate code and making state management more efficient.

Source Code : https://github.com/BugBlitz98/ReactRedux

Congratulations! You've successfully set up Redux Toolkit in your React TypeScript project. By leveraging Redux Toolkit's simplified API and TypeScript's type safety, you've made your state management more efficient and understandable. 


Happy coding!🙂




Previous Post Next Post

Contact Form