Part 82: Displaying Cart Items with React: A Step-by-Step Guide
[Pages] Shopping Cart (Exercises)

Creating an intuitive and informative cart page is a crucial aspect of any e-commerce application. In this blog post, we'll walk through the process of fetching and displaying cart items using React, focusing on rendering these items in an HTML table with Tailwind CSS for styling. We'll also explore how to calculate and display item totals and a grand total for the cart.
Step 1: Display Cart Items in a Table
The first step is to display the cart items we fetched earlier in a structured table format. We'll create a CartTable component to handle the display logic, ensuring each cart item is represented with its product title, price, and quantity.
Initial Implementation
Here's how we can start by simply listing each item in a table:
// File: pages/cart.js
import { useQuery } from 'react-query';
import Page from '../components/Page';
import { fetchJson } from '../lib/api';
function CartTable({ cartItems }) {
return (
<table>
<thead>
<tr>
<th className="px-4 py-2">Product</th>
<th className="px-4 py-2">Price</th>
<th className="px-4 py-2">Quantity</th>
</tr>
</thead>
<tbody>
{cartItems.map((cartItem) => (
<tr key={cartItem.id}>
<td className="px-4 py-2">{cartItem.product.title}</td>
<td className="px-4 py-2 text-right">{cartItem.product.price}</td>
<td className="px-4 py-2 text-right">{cartItem.quantity}</td>
</tr>
))}
</tbody>
</table>
);
}
function CartPage() {
const query = useQuery('cartItems', () => fetchJson('/api/cart'));
const cartItems = query.data;
console.log('[CartPage] cartItems:', cartItems);
return (
<Page title="Cart">
{cartItems && <CartTable cartItems={cartItems} />}
</Page>
);
}
export default CartPage;Explanation
Table Structure: We use a simple HTML table with headings for "Product", "Price", and "Quantity".
Mapping Items: We iterate over the
cartItemsarray to create a table row for each item.Tailwind CSS: Utility classes like
px-4andpy-2are used for padding, whiletext-rightaligns numeric content to the right.
Step 2: Calculating Totals and Formatting Prices
Next, we'll enhance our table to include a total for each item and a grand total for the cart. We'll also format prices to display as currency.
Enhancements
Helper Functions: We introduce
buildCartto calculate item totals and a grand total, andformatCurrencyto format numbers as dollar amounts.Table Modifications: We add a column for item totals and a footer for the grand total.
// File: pages/cart.js
import { useQuery } from 'react-query';
import Page from '../components/Page';
import { fetchJson } from '../lib/api';
function formatCurrency(value) {
return '$' + value.toFixed(2);
}
function buildCart(cartItems) {
let total = 0.0;
const items = [];
for (const cartItem of cartItems) {
const itemTotal = cartItem.product.price * cartItem.quantity;
total += itemTotal;
items.push({ ...cartItem, total: itemTotal });
}
return { items, total };
}
function CartTable({ cartItems }) {
const cart = buildCart(cartItems);
return (
<table>
<thead>
<tr>
<th className="px-4 py-2">Product</th>
<th className="px-4 py-2">Price</th>
<th className="px-4 py-2">Quantity</th>
<th className="px-4 py-2">Total</th>
</tr>
</thead>
<tbody>
{cart.items.map((cartItem) => (
<tr key={cartItem.id}>
<td className="px-4 py-2">{cartItem.product.title}</td>
<td className="px-4 py-2 text-right">{formatCurrency(cartItem.product.price)}</td>
<td className="px-4 py-2 text-right">{cartItem.quantity}</td>
<td className="px-4 py-2 text-right">{formatCurrency(cartItem.total)}</td>
</tr>
))}
</tbody>
<tfoot>
<tr>
<th className="px-4 py-2 text-left">Total</th>
<th></th>
<th></th>
<th className="px-4 py-2 text-right">{formatCurrency(cart.total)}</th>
</tr>
</tfoot>
</table>
);
}Explanation
Total Calculation: The
buildCartfunction calculates a total for each item and a grand total for the cart.Currency Formatting: The
formatCurrencyfunction ensures prices are displayed in a consistent currency format.Table Footer: A footer row is added to display the grand total, enhancing the table's functionality.
Conclusion
By following these steps, we have successfully transformed our cart page into a comprehensive display of cart items, including individual and grand totals. This setup not only improves user experience but also provides clarity and precision in the shopping process. As you continue developing your application, consider further enhancements such as handling cart updates and integrating additional styling for a polished look.
Last updated