In this tutorial, we’ll create shopping add to cart page in React Material-UI (MUI) version 5. We’ll create a simple product card with an Add to Cart button and a cart page that lists all added items. Please note that you’ll need to have a React project set up with MUI 5 installed.
Install & Setup Vite + React + Typescript + MUI 5
React MUI 5 Simple Add to Cart Page
First, let’s create a ProductCard component that displays a product and an Add to Cart button.
// ProductCard.jsx
import React from 'react';
import { Card, CardMedia, CardContent, CardActions, Typography, Button } from '@mui/material';
const ProductCard = ({ product, onAddToCart }) => {
return (
<Card sx={{ maxWidth: 345 }}>
<CardMedia
component="img"
height="140"
image={product.image}
alt={product.name}
/>
<CardContent>
<Typography gutterBottom variant="h5" component="div">
{product.name}
</Typography>
<Typography variant="body2" color="text.secondary">
{product.description}
</Typography>
</CardContent>
<CardActions>
<Button size="small" onClick={() => onAddToCart(product)}>
Add to Cart
</Button>
</CardActions>
</Card>
);
};
export default ProductCard;
Then, let’s create a CartPage component that lists all the items that have been added to the cart.
// CartPage.jsx
import React from 'react';
import { List, ListItem, ListItemText, ListItemAvatar, Avatar, Typography } from '@mui/material';
const CartPage = ({ cartItems }) => {
return (
<List>
{cartItems.length === 0 ? (
<Typography variant="h6">Your cart is empty</Typography>
) : (
cartItems.map((item) => (
<ListItem key={item.id}>
<ListItemAvatar>
<Avatar alt={item.name} src={item.image} />
</ListItemAvatar>
<ListItemText primary={item.name} secondary={`Quantity: ${item.quantity}`} />
</ListItem>
))
)}
</List>
);
};
export default CartPage;
Now, you’ll need to manage the state in your main component or page. Here’s a simple App component that brings everything together.
// App.js
import React, { useState } from 'react';
import ProductCard from './ProductCard';
import CartPage from './CartPage';
import { Container, Grid } from '@mui/material';
const products = [
// Replace with your actual product data
{ id: 1, name: 'Product 1', description: 'This is product 1', image: 'path/to/image1.jpg' },
{ id: 2, name: 'Product 2', description: 'This is product 2', image: 'path/to/image2.jpg' },
// ... more products
];
const App = () => {
const [cart, setCart] = useState([]);
const handleAddToCart = (product) => {
setCart((prevCart) => {
const isProductInCart = prevCart.find((item) => item.id === product.id);
if (isProductInCart) {
return prevCart.map((item) =>
item.id === product.id ? { ...item, quantity: item.quantity + 1 } : item
);
}
return [...prevCart, { ...product, quantity: 1 }];
});
};
return (
<Container>
<Grid container spacing={4}>
{products.map((product) => (
<Grid item key={product.id} xs={12} sm={6} md={4}>
<ProductCard product={product} onAddToCart={handleAddToCart} />
</Grid>
))}
</Grid>
<CartPage cartItems={cart} />
</Container>
);
};
export default App;
React MUI 5 Product Listing Page with Shopping Cart Overview
We will Create a fully functional shopping cart using React and MUI 5, providing features like tracking the total price and quantity of items. you can split React components to improve code clarity and organization.
import { useState } from "react";
import {
Card,
CardMedia,
CardContent,
CardActions,
Typography,
Button,
Grid,
Box,
List,
ListItem,
ListItemText,
Divider,
Paper,
} from "@mui/material";
const initialProducts = [
{
id: 1,
name: "Laptop",
price: 999,
description: "High-performance laptop",
image: "https://via.placeholder.com/100x100",
},
{
id: 2,
name: "Smartphone",
price: 699,
description: "Latest model smartphone",
image: "https://via.placeholder.com/100x100",
},
// Add more products as needed
];
const ProductCard = ({ product, onAdd }) => (
<Card raised>
<CardMedia
component="img"
height="140"
image={product.image}
alt={product.name}
/>
<CardContent>
<Typography gutterBottom variant="h6" component="div">
{product.name}
</Typography>
<Typography variant="body2" color="text.secondary">
{product.description}
</Typography>
<Typography variant="body1">${product.price.toFixed(2)}</Typography>
</CardContent>
<CardActions>
<Button size="small" variant="contained" onClick={() => onAdd(product)}>
Add to Cart
</Button>
</CardActions>
</Card>
);
const ShoppingCartOverview = ({ cartItems }) => (
<Paper elevation={3} sx={{ p: 2 }}>
<Typography variant="h6" gutterBottom>
Shopping Cart
</Typography>
<Divider />
<List>
{cartItems.map((item, index) => (
<ListItem key={index} divider>
<ListItemText
primary={item.name}
secondary={`Quantity: ${item.quantity}`}
/>
<Typography variant="body2">
${(item.price * item.quantity).toFixed(2)}
</Typography>
</ListItem>
))}
</List>
<Typography variant="h6">
Total: $
{cartItems
.reduce((total, item) => total + item.price * item.quantity, 0)
.toFixed(2)}
</Typography>
</Paper>
);
const ProductListingPage = () => {
const [products] = useState(initialProducts);
const [cart, setCart] = useState([]);
const handleAddToCart = (productToAdd) => {
setCart((prevCart) => {
const productExists = prevCart.find(
(item) => item.id === productToAdd.id
);
if (productExists) {
return prevCart.map((item) =>
item.id === productToAdd.id
? { ...item, quantity: item.quantity + 1 }
: item
);
}
return [...prevCart, { ...productToAdd, quantity: 1 }];
});
};
return (
<Box sx={{ flexGrow: 1, p: 2 }}>
<Grid container spacing={2}>
<Grid item xs={12} md={8}>
<Grid container spacing={2}>
{products.map((product) => (
<Grid item key={product.id} xs={12} sm={6} md={4}>
<ProductCard product={product} onAdd={handleAddToCart} />
</Grid>
))}
</Grid>
</Grid>
<Grid item xs={12} md={4}>
<ShoppingCartOverview cartItems={cart} />
</Grid>
</Grid>
</Box>
);
};
export default ProductListingPage;