Introduction to Redux

It is a predictable state management library for JavaScript applications, commonly used with React. It helps manage and centralize application state, making state changes predictable and easier to debug. Redux = Context API + useReducer Why Use Redux? Centralized State → Stores global state in a single place (Redux store) Predictability → State changes follow strict rules, making debugging easier Easier Debugging → Tools like Redux DevTools help track state changes Better State Management → Useful in large applications with complex state interactions Core Concepts of Redux Store A centralized place to hold the application's state. Actions Plain JavaScript objects that describe what should change in the state. Reducers Pure functions that specify how the state changes based on actions. Dispatch Sends actions to update the store. Selectors Functions that extract and format data from the store. 1) Store It completely stores all the states in one place and making it easier for all the components to access any state store.js import { configureStore } from '@reduxjs/toolkit'; import cartReducer from './cartSlice'; const store = configureStore({ reducer: { cart: cartReducer, }, }); export default store; 2) Action It is a plain JavaScript object that describes what should happen in the application. Actions are sent to the reducer to update the state. const addItem = (item) => ({ type: 'ADD_ITEM', payload: item, }); 3) Reducer It is a function that determines changes to an application’s state. It uses the current state and an action to compute and return a new state. It can be said like Change handler similar to Event Handler It uses initial state and actions available to create a new state 4) Slice This is used to organize all the reducers for each webpage as a separate entity We can add initial states and reducers along with api calls import { createSlice } from '@reduxjs/toolkit'; const cartSlice = createSlice({ name: 'cart', initialState: { cartProductIds: [], }, reducers: { addToCart: (state, action) => { state.cartProductIds = [action.payload, ...state.cartProductIds]; }, removeFromCart: (state, action) => { const indexOfId = state.cartProductIds.indexOf(action.payload); if (indexOfId !== -1) { state.cartProductIds.splice(indexOfId, 1); } }, clearAllItems: (state) => { state.cartProductIds = []; }, }, }); export const { addToCart, removeFromCart, clearAllItems } = cartSlice.actions; export default cartSlice.reducer; 5) Provider import React from 'react'; import ReactDOM from 'react-dom'; import { Provider } from 'react-redux'; import store from './app/store'; import App from './App'; ReactDOM.render( , document.getElementById('root') ); Hooks required for redux 1) useSelector This is used to extract particular state from redux store const selectedData = useSelector((state) => state.someData); 2) useDispatch This is used to send off actions to the redux store // src/features/cart/CartComponent.js import React from 'react'; import { useSelector, useDispatch } from 'react-redux'; import { addToCart, removeFromCart, clearAllItems } from './cartSlice'; const CartComponent = () => { const cartProductIds = useSelector((state) => state.cart.cartProductIds); const dispatch = useDispatch(); return ( Cart {cartProductIds.map((id) => ( Product ID: {id} dispatch(removeFromCart(id))}>Remove ))} dispatch(clearAllItems())}>Clear All dispatch(addToCart(123))}>Add Product 123 ); }; export default CartComponent; Redux Thunk It is a middleware that allows you to write asynchronous logic (like API calls) inside Redux actions. It enables action creators to return functions instead of plain objects. import { createAsyncThunk, createSlice } from '@reduxjs/toolkit'; // Define an async thunk to fetch data export const fetchUser = createAsyncThunk( 'user/fetchUser', async (userId) => { const response = await fetch(`https://jsonplaceholder.typicode.com/users/${userId}`); return response.json(); } ); const userSlice = createSlice({ name: 'user', initialState: { data: null, loading: false, error: null }, reducers: {}, extraReducers: (builder) => { builder .addCase(fetchUser.pending, (state) => { state.loading = true; }) .addCase(fetchUser.fulfilled, (state, action) => { state.loading = false; state.data = action.payload; }) .addCase(fetchUser.rejected, (state, action) => { state.loading = false; state.error = action.error.message; }); } }); export default userSlice.reducer; Redux Toolkit (RT

Mar 11, 2025 - 04:29
 0
Introduction to Redux

It is a predictable state management library for JavaScript applications, commonly used with React. It helps manage and centralize application state, making state changes predictable and easier to debug.

Redux = Context API + useReducer

Why Use Redux?

Centralized State → Stores global state in a single place (Redux store)
Predictability → State changes follow strict rules, making debugging easier
Easier Debugging → Tools like Redux DevTools help track state changes
Better State Management → Useful in large applications with complex state interactions

Core Concepts of Redux

Store
A centralized place to hold the application's state.

Actions
Plain JavaScript objects that describe what should change in the state.

Reducers
Pure functions that specify how the state changes based on actions.

Dispatch
Sends actions to update the store.

Selectors
Functions that extract and format data from the store.

1) Store

It completely stores all the states in one place and making it easier for all the components to access any state

store.js

import { configureStore } from '@reduxjs/toolkit';

import cartReducer from './cartSlice';



const store = configureStore({

  reducer: {

    cart: cartReducer,

  },

});

export default store;

2) Action
It is a plain JavaScript object that describes what should happen in the application. Actions are sent to the reducer to update the state.

const addItem = (item) => ({
  type: 'ADD_ITEM',
  payload: item,
});

3) Reducer

  • It is a function that determines changes to an application’s state. It uses the current state and an action to compute and return a new state.
  • It can be said like Change handler similar to Event Handler
  • It uses initial state and actions available to create a new state

4) Slice

  • This is used to organize all the reducers for each webpage as a separate entity
  • We can add initial states and reducers along with api calls
import { createSlice } from '@reduxjs/toolkit';

const cartSlice = createSlice({

  name: 'cart',

  initialState: {

    cartProductIds: [],

  },

  reducers: {

    addToCart: (state, action) => {

      state.cartProductIds = [action.payload, ...state.cartProductIds];

    },

    removeFromCart: (state, action) => {

      const indexOfId = state.cartProductIds.indexOf(action.payload);

      if (indexOfId !== -1) {

        state.cartProductIds.splice(indexOfId, 1);

      }

    },

    clearAllItems: (state) => {

      state.cartProductIds = [];

    },

  },

});



export const { addToCart, removeFromCart, clearAllItems } = cartSlice.actions;

export default cartSlice.reducer;

5) Provider

import React from 'react';

import ReactDOM from 'react-dom';

import { Provider } from 'react-redux';

import store from './app/store';

import App from './App';



ReactDOM.render(

  <Provider store={store}>

    <App />

  </Provider>,

  document.getElementById('root')

);

Hooks required for redux

1) useSelector

This is used to extract particular state from redux store

const selectedData = useSelector((state) => state.someData);

2) useDispatch

This is used to send off actions to the redux store

// src/features/cart/CartComponent.js

import React from 'react';

import { useSelector, useDispatch } from 'react-redux';

import { addToCart, removeFromCart, clearAllItems } from './cartSlice';



const CartComponent = () => {

  const cartProductIds = useSelector((state) => state.cart.cartProductIds);

  const dispatch = useDispatch();



  return (

    <div>

      <h1>Cart</h1>

      <ul>

        {cartProductIds.map((id) => (

          <li key={id}>

            Product ID: {id}

            <button onClick={() => dispatch(removeFromCart(id))}>Remove</button>

          </li>

        ))}

      </ul>

      <button onClick={() => dispatch(clearAllItems())}>Clear All</button>

      <button onClick={() => dispatch(addToCart(123))}>Add Product 123</button>

    </div>

  );

};



export default CartComponent;

Redux Thunk

It is a middleware that allows you to write asynchronous logic (like API calls) inside Redux actions. It enables action creators to return functions instead of plain objects.

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

// Define an async thunk to fetch data
export const fetchUser = createAsyncThunk(
  'user/fetchUser',
  async (userId) => {
    const response = await fetch(`https://jsonplaceholder.typicode.com/users/${userId}`);
    return response.json();
  }
);

const userSlice = createSlice({
  name: 'user',
  initialState: { data: null, loading: false, error: null },
  reducers: {},
  extraReducers: (builder) => {
    builder
      .addCase(fetchUser.pending, (state) => { 
        state.loading = true; 
      })
      .addCase(fetchUser.fulfilled, (state, action) => { 
        state.loading = false;
        state.data = action.payload; 
      })
      .addCase(fetchUser.rejected, (state, action) => { 
        state.loading = false;
        state.error = action.error.message; 
      });
  }
});

export default userSlice.reducer;

Redux Toolkit (RTK)

It is the official, recommended way to write Redux logic. It simplifies state management by reducing boilerplate code, improving performance, and making Redux easier to use.

Stay Connected!
If you enjoyed this post, don’t forget to follow me on social media for more updates and insights:

Twitter: madhavganesan
Instagram: madhavganesan
LinkedIn: madhavganesan