Open In App

Implementing Add to Cart functionality using Redux toolkit in React

Last Updated : 14 Jan, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

Add To Cart functionality is one of the important components of the E-commerce platform. In this article, we are going to learn how to implement Add to Cart functionality using React JS and Redux Toolkit.

Preview of final output: Let us have a look at how the final output will look like.

prv

Prerequisites

Approach to implement Add to Cart Functionality:

  • Create five folders named Cart, Components, Pages, Reducer and Slices in src directory and create index.jsx and RenderCartItems.jsx in Cart, Product_card.jsx in Components, Home.jsx in Pages, index.jsx in Reducer and CartSlice.jsx in Slices respectively.
  • Implement store inside index.js file as given in example.
  • Implement cartReducer inside index.js file in reducer folder.
  • Create CartSlice.jsx in Slices folder and implement functionality of add to cart and remove from cart in it.
  • Create Home.jsx page in Pages folder and fetch product details.
  • Inside Cart folder create index.js and RenderCartItems.jsx to create UI for cart.
  • In last step we will call Home page and cart in App.js file.

Steps to Create and Configure React App with redux toolkit

Step 1: Create a react app using command “npx create-react-app app-name”.

npx create-react-app app-name

Step 2: Install the required dependencies

npm install react-redux @reduxjs/toolkit
npm install react-hot-toast
npm i react-router-dom react-icons

Project Structure:

pj-str-

The updated dependencies in package.json file will look like:

"dependencies": {
"@reduxjs/toolkit": "^2.0.1",
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-hot-toast": "^2.4.1",
"react-icons": "^4.12.0",
"react-redux": "^9.0.4",
"react-router-dom": "^6.21.1",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
}

Example: Create the folder structure and insert the following files accordingly.

Javascript




// Cart/index.jsx
 
import { useSelector } from "react-redux"
import RenderCartItems from "./RenderCartItems"
 
export default function Cart() {
    const {total, totalItems} = useSelector((state) => state.cart)
    return (
        <div >
            <h1>Your Cart</h1>
            <p >{totalItems} Items in cart</p>
            {
                total>0
                ? (
                    <div >
                        <RenderCartItems />
                    </div>
                )
                : (
                    <p>Your Cart is empty</p>
                )
            }
        </div>
    )
}


Javascript




// Cart/RenderCartItems.jsx
import React from "react";
import { useDispatch, useSelector } from "react-redux";
import { RiDeleteBin6Line } from "react-icons/ri";
import { removeFromCart } from "../Slices/CartSlice";
 
export default function RenderCartItems() {
    const { cart } = useSelector((state) => state.cart);
    const dispatch = useDispatch();
 
    return (
        <div>
            {cart.map((dataObj, index) => (
                <div
                    key={index}
                    className={`flex w-full flex-wrap i
                                tems-start justify-between gap-6
                        ${
                            index !== cart.length - 1 &&
                            "border-b border-b-richblack-400 pb-6"
                        }
                        ${index !== 0 && "mt-6"} `}
                >
                    <div>
                        <div>{dataObj.title}</div>
                        <img
                            src={dataObj.image}
                            width={200}
                            height={150}
                            alt=""
                        />
                        <p>{dataObj.description}</p>
                    </div>
 
                    <div>
                        <button
                            onClick={() =>
                                dispatch(removeFromCart(dataObj._id))
                            }
                        >
                            <RiDeleteBin6Line size={20} />
                        </button>
                    </div>
                </div>
            ))}
        </div>
    );
}


Javascript




// Components/Product_cart.jsx
 
import React from 'react'
import { addToCart } from '../Slices/CartSlice';
import { useDispatch } from 'react-redux';
 
const Product_card = ({ dataObj }) => {
    const dispatch = useDispatch();
 
    const handleAddToCart = () => {
        console.log("dispatching add to cart")
        dispatch(addToCart(dataObj));
        return;
    }
 
    return (
        <div
            style={{
                display: 'flex',
                flexWrap: 'wrap',
                gap: '70px',
                justifyContent: 'space-around',
                marginTop: '70px'
            }}
        >
            <div
                style={{
                    width: "15em",
                    backgroundColor: "#35D841",
                    padding: 2,
                    borderRadius: 10,
                    marginBlock: 10,
                }}
            >
                <p style={{ fontSize: 20, color: 'black' }}>{dataObj.title}</p>
                <img src={dataObj.image} alt="" height={200} width={200} />
                <p>{dataObj.description}</p>
                <button
                    onClick={handleAddToCart}
                >
                    Add to cart
                </button>
            </div>
        </div>
    )
}
 
export default Product_card


Javascript




// Pages/Home.jsx
 
import React, { useState } from "react";
import { FaCartArrowDown } from "react-icons/fa";
import { Link } from "react-router-dom";
import Product_card from "../Components/Product_card";
 
const items = [
    {
        id: 1,
        title: "GeeksForGeeks bag",
        price: 109.95,
        description:
            "Your perfect pack for everyday use and walks in the forest.",
        category: "bag",
        rating: {
            rate: 3.9,
            count: 120,
        },
    },
    {
        id: 2,
        title: "GeeksForGeeks tshirt",
        price: 22.3,
        description: "Slim-fitting style,black tshirt. From geeksforgeeks",
        category: "men's clothing",
        rating: {
            rate: 4.1,
            count: 259,
        },
    },
];
 
const Home = () => {
    return (
        <div>
            <Link to={"/cart"}>
                <FaCartArrowDown size={40} color="#35D841" />
            </Link>
            <div
                style={{
                    display: "Flex",
                    justifyContent: "space-around",
                }}
            >
                {items.map((dataObj, index) => {
                    return <Product_card dataObj={dataObj} />;
                })}
            </div>
        </div>
    );
};
 
export default Home;


Javascript




// Reducer/index.jsx
 
import { combineReducers } from "@reduxjs/toolkit";
 
import cartReducer from "../Slices/CartSlice"
 
const rootReducer = combineReducers({
    cart: cartReducer,
})
 
export default rootReducer


Javascript




// Slices/CartSlice.jsx
 
import { createSlice } from "@reduxjs/toolkit";
import { toast } from "react-hot-toast";
 
const initialState = {
    cart: localStorage.getItem("cart")
        ? JSON.parse(localStorage.getItem("cart"))
        : [],
    total: localStorage.getItem("total")
        ? JSON.parse(localStorage.getItem("total"))
        : 0,
    totalItems: localStorage.getItem("totalItems")
        ? JSON.parse(localStorage.getItem("totalItems"))
        : 0,
}
 
const cartSlice = createSlice({
    name: "cart",
    initialState,
    reducers: {
        addToCart: (state, action) => {
            const item = action.payload
             
            state.cart.push(item)
            state.totalItems++
            state.total += item.price
            localStorage.setItem("cart", JSON.stringify(state.cart))
            localStorage.setItem("total", JSON.stringify(state.total))
            localStorage.setItem("totalItems", JSON.stringify(state.totalItems))
            toast.success("Item added to cart")
        },
         
        removeFromCart: (state, action) => {
            const itemId = action.payload
            const index = state.cart.findIndex((item) => item._id === itemId)
 
            if (index >= 0) {
                 
                state.totalItems--
                state.total -= state.cart[index].price
                state.cart.splice(index, 1)
                localStorage.setItem("cart", JSON.stringify(state.cart))
                localStorage.setItem("total", JSON.stringify(state.total))
                localStorage.setItem("totalItems", JSON.stringify(state.totalItems))
                toast.success("Item removed from cart")
            }
        },
 
    }
})
 
export const { addToCart, resetCart, removeFromCart } = cartSlice.actions
export default cartSlice.reducer;


Javascript




// App.js
 
import './App.css';
import { Route, Routes } from "react-router-dom";
import Cart from "./Cart/index"
import Home from "./Pages/Home";
 
function App() {
    return (
        <div className="App">
            <Routes>
                <Route path="/cart" element={<Cart />} />
                <Route path="/" element={<Home />} />
            </Routes>
        </div>
    );
}
 
export default App;


Javascript




// index.js
 
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import rootReducer from './Reducer';
import { Provider } from "react-redux";
import { configureStore } from "@reduxjs/toolkit"
import { BrowserRouter } from 'react-router-dom';
import { Toaster } from 'react-hot-toast';
const root = ReactDOM.createRoot(document.getElementById('root'));
 
const store = configureStore({
    reducer: rootReducer,
})
 
root.render(
    <React.StrictMode>
        <Provider store={store}>
            <BrowserRouter>
                <App />
                <Toaster />
            </BrowserRouter>
        </Provider>
    </React.StrictMode>
);
reportWebVitals();


Steps to Run the Application:

Step 1: Type following command in your terminal.

npm start

Step 2: Locate the given URL in your browser.

http://localhost:3000/

Output:

React-App---Google-Chrome-2024-01-09-23-17-25



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads