Add to Cart Feature in React with Redux Toolkit

Rmag Breaking News

Redux, a key part of managing state in React apps, can seem daunting at first. But there’s a simpler way to approach it. In this blog, I’ll share my journey of understanding Redux and using it in a straightforward manner. I’ll show you how to easily add features like a shopping cart to your React app with Redux. Let’s explore Redux together and make state management in React simpler.

Setting Up Your Environment

Before diving into the code, make sure you have Node.js and npm (or yarn) installed on your machine. Create a new React application using Vite:

npm create vite@latest

Next, install Redux Toolkit:

npm install @reduxjs/toolkit react-redux

Creating the Redux Store

First, let’s create a Redux store to manage our application state. Inside the src directory, create a new folder called “store” and inside it, create a file named “store.js”:

import { configureStore } from “@reduxjs/toolkit”;
import cartReducer from “./cartSlice”;

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

export default store;

Defining the Cart Slice

Now, let’s define our cart slice, which includes the reducer and action creators. Create a new file named “cartSlice.js” in the “redux” folder:

import { createSlice } from “@reduxjs/toolkit”;

const initialState = { itemList: [], totalQuantity: 0, showCart: false };

const cartSlice = createSlice({
name: “cart”,
initialState,
reducers: {
addToCart(state, action) {
const newItem = action.payload;
const existingItem = state.itemList.find(
(item) => item.id === newItem.id
);
if (existingItem) {
existingItem.quantity++;
existingItem.totalPrice = existingItem.price * existingItem.quantity;
} else {
state.itemList.push({
name: action.payload.name,
price: action.payload.price,
totalPrice: action.payload.totalPrice,
id: action.payload.id,
quantity: 1,
});
}
},
removeFromCart(state, action) {
const findItem = state.itemList.find(
(item) => item.id === action.payload.id
);
if (findItem.quantity === 1) {
state.itemList = state.itemList.filter(
(item) => item.id != action.payload.id
);
} else {
findItem.quantity–;
findItem.totalPrice -= findItem.price;
}
},
setShowCart(state) {
state.showCart = !state.showCart;
},
},
});

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

This completes the redux setup now data insertion and fetch can be done using useDispatch and useSelector respectively. Here’s the way:
This is how you can add item to cart:

import React from “react”;
import { useDispatch, useSelector } from “react-redux”;
import { addToCart } from “./store/cartSlice”;

const ParticularItem = ({ name, id, price, desc }) => {
const dispatch = useDispatch();
const addCart = () => {
dispatch(addToCart({ name, id, price, desc, totalPrice: price }));
};

return (
<div>
<h1>{name}</h1>
<h1>{price}</h1>
<h1>{desc}</h1>
<button onClick={addCart} className=”adder”>
Add to Cart
</button>
</div>
);
};

export default ParticularItem;

This is how you can show the elements in cart:

import React from “react”;
import { useDispatch, useSelector } from “react-redux”;
import IndividualAdded from “./IndividualAdded”;

const AddedElements = () => {
const elements = useSelector((state) => state.reducer.itemList);
if (elements.length > 0) {
return (
<>
<ul>
{elements.map((item) => (
<li key={item.id}>
<IndividualAdded
name={item.name}
price={item.price}
quantity={item.quantity}
totalPrice={item.totalPrice}
id={item.id}
/>
</li>
))}
</ul>
</>
);
} else {
return <h1>Cart is empty</h1>;
}
};

export default AddedElements;

Other files:

App.jsx

import React from “react”;
import Items from “./Items”;
import Header from “./Header”;
import AddedElements from “./AddedElements”;
import { useSelector } from “react-redux”;

const App = () => {
const checkState = useSelector((state) => state.reducer.showCart);

return (
<>
<Header />
<Items />
{checkState && <AddedElements />}
</>
);
};

export default App;

Header.jsx

import React from “react”;
import { useSelector, useDispatch } from “react-redux”;
import { setShowCart } from “./store/cartSlice”;

const Header = () => {
const dispatch = useDispatch();
const elements = useSelector((state) => state.reducer.itemList);
const state = useSelector((state) => state.reducer.showCart);
const showElements = () => {
dispatch(setShowCart(state));
};
return (
<>
<header>
<h1>WELCOME</h1>
<button onClick={showElements}>Cart: {elements.length}</button>
</header>
</>
);
};

export default Header;

IndividualAdded.jsx

import React from “react”;
import { useDispatch } from “react-redux”;
import { addToCart, removeFromCart } from “./store/cartSlice”;

const IndividualAdded = ({ name, price, quantity, totalPrice, id }) => {
const dispatch = useDispatch();
const increment = () => {
dispatch(addToCart({ name, price, id }));
};
const decrement = () => {
dispatch(removeFromCart({ id, quantity, totalPrice, price }));
};
return (
<div className=”container2″>
<div className=”card”>
<h3 className=”first”>{name}</h3>
<h3 className=”second”>{price}</h3>
<h3 className=”third”>{quantity}</h3>
<h3 className=”forth”>{totalPrice}</h3>
<button onClick={increment}>+</button>
<button onClick={decrement}>-</button>
</div>
</div>
);
};

export default IndividualAdded;

Items.jsx

import React from “react”;
import ParticularItem from “./ParticularItem”;
import “./styles/items.scss”;

const Items = () => {
const items = [
{ name: “Laptop”, price: 123, desc: “new laptop”, id: 1 },
{ name: “Shoes”, price: 12, desc: “new shoe”, id: 2 },
];
return (
<>
<div className=”container”>
<ul>
{items.map((item) => (
<li key={item.price}>
<ParticularItem
name={item.name}
price={item.price}
desc={item.desc}
id={item.id}
/>
</li>
))}
</ul>
</div>
</>
);
};

export default Items;

and lastly main.jsx

import React from “react”;
import ReactDOM from “react-dom/client”;
import App from “./App.jsx”;
import { Provider } from “react-redux”;
import { store } from “./store/store.js”;

ReactDOM.createRoot(document.getElementById(“root”)).render(
<React.StrictMode>
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>
);

*Styling is totally upto you this is just the implementation
items.scss

* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.container {
padding: 2rem 0 0 0;
width: 100vw;
ul {
display: flex;
justify-content: space-evenly;
list-style: none;
}
}
header {
display: flex;
justify-content: space-between;
padding: 2rem 10rem 0 10rem;
button {
font-size: 1.25rem;
padding: 2rem;
cursor: pointer;
}
}
.adder {
font-size: 1.25rem;
padding: 2rem;
cursor: pointer;
}
.card {
display: flex;
justify-content: space-evenly;
}

Leave a Reply

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