MERN Stack

How to Build a Complete E-Commerce Application with React-Redux Toolkit, Node.js, Express, MongoDB, and LocalStorage

Introduction

Building a full-stack e-commerce application can be a rewarding project for honing your development skills. This step-by-step guide will help you create an e-commerce app with React, Redux Toolkit, Node.js, Express, MongoDB, and localStorage for managing the cart.

E-commerce has revolutionized the way businesses operate and customers shop. Creating an e-commerce application is not just a valuable skill but also an opportunity to build a real-world, high-impact project. This tutorial walks you through the process of developing a full-stack e-commerce app from scratch. The backend leverages the power of Node.js and Express to create APIs and connect to a MongoDB database, while the frontend uses React and Redux Toolkit to manage state efficiently. Additionally, the application uses localStorage to persist cart data, ensuring a seamless user experience. Whether you’re a beginner or an experienced developer, this guide will help you build a feature-rich e-commerce platform with functionality like product display, cart management, and more. By the end, you’ll have a robust application that you can deploy and expand with advanced features like authentication and payment gateways.


Step 1: Setting Up the Backend

1.1 Initialize the Project

  • Create a new directory and navigate into it.
mkdir ecommerce-app && cd ecommerce-app
  • Initialize a Node.js project:
npm init -y

1.2 Install Dependencies

Install the necessary backend dependencies:

npm install express mongoose dotenv body-parser cors
npm install --save-dev nodemon

1.3 Configure the Server

Create a file named server.js in the root directory and set up the Express server:

const express = require('express');
const mongoose = require('mongoose');
const cors = require('cors');
const dotenv = require('dotenv');

dotenv.config();

const app = express();
app.use(cors());
app.use(express.json());

// Connect to MongoDB
mongoose.connect(process.env.MONGO_URI, {
  useNewUrlParser: true,
  useUnifiedTopology: true,
})
  .then(() => console.log('MongoDB connected'))
  .catch((err) => console.error(err));

// API routes
app.get('/', (req, res) => {
  res.send('API is running...');
});

const productRoutes = require(‘./routes/productRoutes’);
const cartRoutes = require(‘./routes/cartRoutes’);
const customerRoutes = require(‘./routes/customerRoutes’);
const orderRoutes = require(‘./routes/orderRoutes’);
const orderDetailsRoutes = require(‘./routes/orderDetailsRoutes’);

app.use(‘/api/products’, productRoutes);
app.use(‘/api/cart’, cartRoutes);
app.use(‘/api/customers’, customerRoutes);
app.use(‘/api/orders’, orderRoutes);
app.use(‘/api/order-details’, orderDetailsRoutes);


const PORT = process.env.PORT || 5000;
app.listen(PORT, () => console.log(`Server running on port ${PORT}`));

1.4 Create Models

Create a models directory and add a Product.js file for product schema:

const mongoose = require('mongoose');

const productSchema = mongoose.Schema({
  name: { type: String, required: true },
  price: { type: Number, required: true },
  description: { type: String },
  image: { type: String },
}, { timestamps: true });

module.exports = mongoose.model('Product', productSchema);

1.5 Add Routes

In a routes directory, create a productRoutes.js file:

const express = require('express');
const Product = require('../models/Product');
const router = express.Router();

// Get all products
router.get('/', async (req, res) => {
  const products = await Product.find();
  res.json(products);
});

module.exports = router;

Connect the routes in server.js:

const productRoutes = require('./routes/productRoutes');
app.use('/api/products', productRoutes);

Step 2: Setting Up the Frontend

2.1 Initialize React Project

Create a new React application:

npx create-react-app frontend
cd frontend

2.2 Install Dependencies

Install the necessary packages for state management and API calls:

npm install @reduxjs/toolkit react-redux axios react-router-dom

2.3 Set Up Redux Toolkit

Create a features directory in src and add a cartSlice.js file:

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

const cartSlice = createSlice({
  name: 'cart',
  initialState: {
    cartItems: JSON.parse(localStorage.getItem('cartItems')) || [],
  },
  reducers: {
    addToCart: (state, action) => {
      const item = action.payload;
      const existingItem = state.cartItems.find((x) => x._id === item._id);

      if (existingItem) {
        existingItem.qty += item.qty;
      } else {
        state.cartItems.push(item);
      }

      localStorage.setItem('cartItems', JSON.stringify(state.cartItems));
    },
    removeFromCart: (state, action) => {
      state.cartItems = state.cartItems.filter((x) => x._id !== action.payload);
      localStorage.setItem('cartItems', JSON.stringify(state.cartItems));
    },
  },
});

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

2.4 Configure Redux Store

In src, create a store.js file:

import { configureStore } from '@reduxjs/toolkit';
import cartReducer from './features/cartSlice';

const store = configureStore({
  reducer: {
    cart: cartReducer,
  },
});

export default store;

Wrap the App component with the Provider in index.js:

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import store from './store';
import App from './App';

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
);

Step 3: Fetch and Display Products

3.1 Create API Service

Create a services directory in src and add api.js:

import axios from 'axios';

const API = axios.create({ baseURL: 'http://localhost:5000/api' });

export const fetchProducts = () => API.get('/products');

3.2 Display Products

In the src directory, create a components folder and add a ProductList.js file:

import React, { useEffect, useState } from 'react';
import { fetchProducts } from '../services/api';

const ProductList = () => {
  const [products, setProducts] = useState([]);

  useEffect(() => {
    const getProducts = async () => {
      const { data } = await fetchProducts();
      setProducts(data);
    };
    getProducts();
  }, []);

  return (
    <div>
      {products.map((product) => (
        <div key={product._id}>
          <h3>{product.name}</h3>
          <p>{product.price}</p>
          <button>Add to Cart</button>
        </div>
      ))}
    </div>
  );
};

export default ProductList;

3.3 Add to Cart Functionality

Connect the addToCart action from Redux:

import { useDispatch } from 'react-redux';
import { addToCart } from '../features/cartSlice';

const ProductList = () => {
  const dispatch = useDispatch();

  const handleAddToCart = (product) => {
    dispatch(addToCart({ ...product, qty: 1 }));
  };

  return (
    <div>
      {products.map((product) => (
        <div key={product._id}>
          <h3>{product.name}</h3>
          <p>{product.price}</p>
          <button onClick={() => handleAddToCart(product)}>Add to Cart</button>
        </div>
      ))}
    </div>
  );
};

Step 4: Final Touches

  • Cart Page: Create a Cart.js component to display cart items and allow quantity updates or removal.
  • Styling: Use CSS frameworks like Bootstrap or TailwindCSS for a professional UI.
  • Deployment: Deploy the backend on services like Heroku and the frontend on platforms like Netlify or Vercel.

Summary

This guide provided a comprehensive walkthrough of building a full-stack e-commerce application. By leveraging React-Redux Toolkit for state management, Node.js and Express for the backend, and MongoDB for data storage, you’ve created a scalable and robust application. The inclusion of localStorage ensures seamless cart management. Expand the project further with features like user authentication, payment integration, and order history for a complete e-commerce experience.

 

Leave a Reply

Your email address will not be published. Required fields are marked *