Skip to main content

Command Palette

Search for a command to run...

DAY 61: How I Built an E-Commerce App Using React and Redux Toolkit | ReactJS

Published
โ€ข8 min read
DAY 61: How I Built an E-Commerce App Using React and Redux Toolkit | ReactJS
R

๐Ÿ‘จโ€๐Ÿ’ป Aspiring Software Developer | MERN Stack Developer.๐Ÿš€ Documenting my journey in Full-Stack Development & DSA with Java.๐Ÿ“˜ Focused on writing clean code, building real-world projects, and continuous learning.


๐Ÿš€ Introduction

Welcome to Day 61 of my Web Development Journey!
After building a strong foundation in HTML, CSS, and JavaScript, I transitioned to ReactJS โ€” a powerful library for creating dynamic and interactive user interfaces.

Along the way, I explored different state management techniques in React, including useState, Context API, useReducer, and external libraries like Zustand. More recently, I dove deep into Redux Toolkit (RTK) โ€” one of the most popular and robust solutions for managing state in modern web applications.

Over the past few days, after solidifying my understanding of Redux Toolkit (RTK) and RTK Query, I started building a full-featured E-Commerce Application where Redux Toolkit serves as the backbone for state management and data fetching.

๐Ÿ“‚ You can check out the complete source code of my E-Commerce App in this GitHub repository.

๐Ÿ‘‰ I also share real-time updates and coding insights on Twitter.

Iโ€™m documenting this journey publicly to stay consistent and to share my learnings. Whether youโ€™re just starting with React or looking to strengthen your knowledge of state management and API integration, I hope this blog provides practical insights and helps in your learning journey!

๐Ÿ“… Hereโ€™s What I Covered Over the Last 3 Days

Day 58

  • Set up the e-commerce project (folder structure + store configuration)
  • Implemented routing using React Router
  • Built Header and Footer components

Day 59

  • Completed the Home Page
  • Developed the Collection Page
  • Implemented filtering (by category & subcategory)
  • Added sorting functionality (Relevant, Low to High, High to Low)
  • Implemented search functionality

Day 60

  • Built the Product Detail Page
  • Fetched and displayed a single product by ID
  • Rendered product details dynamically
  • Displayed related products

Now, letโ€™s dive into each of these implementations with explanations and code snippets ๐Ÿ‘‡


1. E-Commerce App with React & Redux Toolkit

This project is an E-Commerce web application built with React, Redux Toolkit (RTK), and React Router.
It is designed with a scalable architecture, focusing on state management with Redux Toolkit and clean separation of UI and logic.

Currently, the app includes:

  • ๐Ÿ“‚ Project setup with folder structure and routing
  • ๐Ÿ  Home page with latest collections & bestsellers
  • ๐Ÿ“š Collection page with filtering, sorting, and search functionality
  • ๐Ÿ“„ Product detail page with related products

Some features like cart, authentication, and checkout are yet to be implemented, but the foundation is already laid for them.

Project Architecture

Folders:

  • store/ โ†’ Redux Toolkit store and slices (productsSlice, filtersSlice)
  • pages/ โ†’ Page-level components (Home, Collection, Product)
  • components/ โ†’ Reusable UI parts (Header, Footer, ProductCard, etc.)
  • routes/ โ†’ App routing configuration
  • App.jsx โ†’ Root layout with Header, Footer, and <Outlet />
  • index.js โ†’ Initializes Redux store + Router

Redux Toolkit State Management

1. Redux Store:

The Redux store is the central state container of the application.
It combines all slices and makes them available across the app using configureStore from Redux Toolkit.

In this project, the store currently manages two main slices:

  • products โ†’ Handles product data (list of products, product by ID, best sellers, latest collections, etc.).
  • filters โ†’ Manages filtering, sorting, and searching state for the Collection page.

By exporting the store, we can wrap the app with <Provider store={store}> in index.js to make this global state accessible throughout the app.

import { configureStore } from "@reduxjs/toolkit";
import productsReducer from "./slices/productSlice.js";
import filtersReducer from "./slices/filtersSlice.js";

export const store = configureStore({
  reducer: {
    products: productsReducer,
    filters: filtersReducer,
  },
});

2. Products Slice:

  • Holds all product data in the store.
  • Provides selectors for latest collections, bestsellers, filtered products, product by ID, and related products.
  • Keeps UI stateless by shifting all logic (filtering, sorting, searching) to selectors.
import { createSelector, createSlice } from "@reduxjs/toolkit";

const productSlice = createSlice({
  name: "products",
  initialState: {
    list: [],
  },
  reducers: {
    loadProducts: (state, action) => {
      state.list = action.payload;
    },
  },
});

export const selectAllProducts = (state) => state.products.list;

export const selectFilteredProducts = createSelector(
  [selectAllProducts, (state) => state.filters],
  (products, filters) => {
    const filteredProducts = products.filter((product) => {
      const matchCategory =
        filters.categories.length === 0 ||
        filters.categories.includes(product.category);
      const matchType =
        filters.types.length === 0 ||
        filters.types.includes(product.subCategory);

      return matchCategory && matchType;
    });

    let sortedProducts = [];
    switch (filters.sortBy) {
      case "low-high":
        sortedProducts = [...filteredProducts].sort(
          (a, b) => a.price - b.price,
        );
        break;

      case "high-low":
        sortedProducts = [...filteredProducts].sort(
          (a, b) => b.price - a.price,
        );
        break;

      default:
        sortedProducts = [...filteredProducts];
    }

    return sortedProducts.filter((product) =>
      product.name.toLowerCase().includes(filters.search.value.toLowerCase()),
    );
  },
);

export const selectLatestCollections = createSelector(
  [selectAllProducts],
  (products) => products.slice(0, 10),
);
export const selectBestSellers = createSelector(
  [selectAllProducts],
  (products) => products.filter((product) => product.bestseller),
);

export const { loadProducts } = productSlice.actions;
export default productSlice.reducer;

Notice how all the business logic is centralized in Redux, so pages simply consume derived state.

3. Filters Slice:

Manages UI filters: categories, types, sorting, and search state.

import { createSlice } from "@reduxjs/toolkit";

const filtersSlice = createSlice({
  name: "filters",
  initialState: {
    categories: [],
    types: [],
    sortBy: "relevant",
    search: {
      showSearch: false,
      value: "",
    },
  },
  reducers: {
    toggleCategory: (state, action) => {
      const category = action.payload;
      if (state.categories.includes(category)) {
        state.categories = state.categories.filter((c) => c !== category);
      } else {
        state.categories.push(category);
      }
    },
    toggleTypes: (state, action) => {
      const type = action.payload;
      if (state.types.includes(type)) {
        state.types = state.types.filter((t) => t !== type);
      } else {
        state.types.push(type);
      }
    },
    updateSortBy: (state, action) => {
      state.sortBy = action.payload;
    },
    showSearchBar: (state) => {
      state.search.showSearch = true;
    },
    hideSearchBar: (state) => {
      state.search.showSearch = false;
    },
    setSearchValue: (state, action) => {
      state.search.value = action.payload;
    },
  },
});

export const selectCategoriesFilter = (state) => state.filters.categories;
export const selectTypesFilter = (state) => state.filters.types;
export const selectShowSearch = (state) => state.filters.search.showSearch;
export const selectSearchValue = (state) => state.filters.search.value;

export const {
  toggleCategory,
  toggleTypes,
  updateSortBy,
  showSearchBar,
  hideSearchBar,
  setSearchValue,
} = filtersSlice.actions;

export default filtersSlice.reducer;

This keeps filtering logic reusable and scalable.

Page-by-Page Walkthrough

1. Home Page

  • Shows Latest Collections โ†’ last 10 products.
  • Shows Best Sellers โ†’ products flagged as bestsellers.
  • Uses selectors selectLatestCollections and selectBestSellers.
import BestSeller from "../components/Home/BestSeller";
import Hero from "../components/Home/Hero";
import LatestCollection from "../components/Home/LatestCollection";
import Policy from "../components/Home/Policy";
import NewsletterBox from "../components/NewsletterBox";

const Home = () => {
  return (
    <div>
      <Hero />
      <LatestCollection />
      <BestSeller/>
      <Policy/>
      <NewsletterBox/>
    </div>
  );
};

export default Home;

The page logic is minimal โ€” data comes directly from the store, already filtered.

2. Collection Page (Core Logic Page)

This is the heart of the app.

Features implemented:

  • Filter by Category (e.g., Men, Women, Kids)
  • Filter by SubCategory (e.g., T-Shirts, Shoes)
  • Sorting (Relevant, Low โ†’ High, High โ†’ Low)
  • Search (real-time, case insensitive)

Logic:

  • Each filter interaction dispatches Redux actions (toggleCategory, updateSortBy, etc.).
  • The UI then simply maps over selectFilteredProducts to render the products.

Thanks to selectors, filtering/sorting/searching donโ€™t clutter the component.

3. Product Detail Page

Features implemented:

  • Fetch product by ID (makeSelectProductById).
  • Display product details (images, price, sizes).
  • Show related products โ†’ same category & subcategory.
const makeSelectProductById = (id) =>
  createSelector([selectAllProducts], (products) =>
    products.find((p) => p._id === id),
  );
const makeSelectRelatedProducts = (category, subCategory, productId) =>
  createSelector([selectAllProducts], (products) =>
    products.filter(
      (p) =>
        p.category === category &&
        p.subCategory === subCategory &&
        p._id !== productId,
    ),
  );

const product = useSelector(makeSelectProductById(productId));
const related = useSelector(
  makeSelectRelatedProducts(product.category, product.subCategory, product.id)
);

This demonstrates parameterized selectors: selectors that take arguments to dynamically fetch derived state

4. Cart Page (Planned)

Not yet implemented.

Will include:

  • A cartSlice to manage items, quantity, and totalPrice.
  • Actions โ†’ addToCart, removeFromCart, updateQuantity.
  • Selector โ†’ selectCartTotal.

5. Authentication (Planned)

Not yet implemented.

Future plans:

  • Add userSlice for login/signup state.
  • Store JWT token & user info in Redux.
  • Show user-specific cart & wishlist.

6. Checkout & Orders (Planned)

Not yet implemented.

Planned flow:

  • After login, users can place orders.
  • An ordersSlice will manage past orders.
  • Checkout process will integrate with RTK Query for API calls.

Work in Progress

This project already demonstrates real-world state management with Redux Toolkit, but several features are still in progress:

  • Cart management
  • User authentication
  • Checkout and orders
  • Contact and About Page

Source Code & Detailed Implementation

This blog provides just an overview of the project and its core logic.
You can explore the complete source code and detailed implementation in my GitHub repository:
๐Ÿ‘‰ E-Commerce App Repository

Key Takeaways

  • Redux Toolkit keeps business logic centralized.
  • Selectors make filtering, sorting, and searching highly optimized.
  • Components remain clean โ†’ they just dispatch actions and consume selectors.
  • Project structure is scalable โ€” new features (cart, wishlist, auth) can be added without breaking existing logic.

2. Whatโ€™s Next

Iโ€™m excited to keep growing and sharing along the way! Hereโ€™s whatโ€™s coming up:

  • Posting new blog updates every 3 days to share what Iโ€™m learning and building.
  • Diving deeper into Data Structures & Algorithms with Java โ€” check out my ongoing DSA Journey Blog for detailed walkthroughs and solutions.
  • Sharing regular progress and insights on X (Twitter) โ€” feel free to follow me there and join the conversation!

Thanks for being part of this journey!


3. Conclusion

Building this E-Commerce App with React and Redux Toolkit has been a great way to apply state management concepts in a real-world project. By keeping all business logic centralized in Redux slices and using selectors for derived state, the app achieves a clean separation of concerns โ€” components remain lean and only focus on rendering UI.

Even though some features like Cart, Wishlist, Authentication, and Checkout are still in progress, the current implementation already shows how Redux Toolkit simplifies complex state management and ensures the project remains scalable and maintainable as it grows.

This project has also reinforced the importance of:

  • Writing reusable selectors for optimized data access.
  • Keeping reducers pure and predictable.
  • Structuring the project in a way that new features can be added without rewriting existing logic.

Iโ€™m excited to keep iterating on this app, adding new features, and integrating it with a backend using RTK Query. Stay tuned for upcoming updates where Iโ€™ll dive deeper into cart management, user authentication, and order handling.

Thanks for reading โ€” and if youโ€™re also learning Redux Toolkit, I hope this blog helps you speed up your journey

More from this blog

Full Stack Development Logs

23 posts

I'm Ritik, a self-taught developer sharing my full stack web dev journeyโ€”daily learnings, projects, and insights as I grow into a full stack developer.