购物车状态管理最佳实践
Jan 30, 2026•160 次浏览•7 销量•reactstate-managementcart
购物车状态管理最佳实践
为什么需要状态管理?
购物车是电商网站的核心功能,需要在多个页面间共享状态。
方案对比
1. Context API (推荐)
优点:
- React 内置,无需额外依赖
- 简单易用
- 适合中小型项目
实现:
import { createContext, useContext, useState } from 'react';
interface CartItem {
id: string;
name: string;
price: number;
quantity: number;
}
interface CartContextType {
items: CartItem[];
addItem: (item: CartItem) => void;
removeItem: (id: string) => void;
updateQuantity: (id: string, quantity: number) => void;
clearCart: () => void;
total: number;
}
const CartContext = createContext<CartContextType | undefined>(undefined);
export function CartProvider({ children }: { children: React.ReactNode }) {
const [items, setItems] = useState<CartItem[]>([]);
const addItem = (item: CartItem) => {
setItems(prev => {
const existing = prev.find(i => i.id === item.id);
if (existing) {
return prev.map(i =>
i.id === item.id
? { ...i, quantity: i.quantity + item.quantity }
: i
);
}
return [...prev, item];
});
};
const removeItem = (id: string) => {
setItems(prev => prev.filter(i => i.id !== id));
};
const updateQuantity = (id: string, quantity: number) => {
if (quantity <= 0) {
removeItem(id);
return;
}
setItems(prev =>
prev.map(i => (i.id === id ? { ...i, quantity } : i))
);
};
const clearCart = () => {
setItems([]);
};
const total = items.reduce((sum, item) => sum + item.price * item.quantity, 0);
return (
<CartContext.Provider
value={{ items, addItem, removeItem, updateQuantity, clearCart, total }}
>
{children}
</CartContext.Provider>
);
}
export function useCart() {
const context = useContext(CartContext);
if (!context) {
throw new Error('useCart must be used within CartProvider');
}
return context;
}
2. 使用 Zustand
import { create } from 'zustand';
import { persist } from 'zustand/middleware';
interface CartStore {
items: CartItem[];
addItem: (item: CartItem) => void;
removeItem: (id: string) => void;
}
export const useCartStore = create<CartStore>()(persist(
(set) => ({
items: [],
addItem: (item) => set((state) => ({
items: [...state.items, item]
})),
removeItem: (id) => set((state) => ({
items: state.items.filter(i => i.id !== id)
}))
}),
{ name: 'cart-storage' }
));
持久化存储
import { useEffect } from 'react';
export function CartProvider({ children }) {
const [items, setItems] = useState(() => {
const saved = localStorage.getItem('cart');
return saved ? JSON.parse(saved) : [];
});
useEffect(() => {
localStorage.setItem('cart', JSON.stringify(items));
}, [items]);
// ...
}
购物车组件
export function Cart() {
const { items, removeItem, updateQuantity, total } = useCart();
return (
<div className="cart">
<h2>购物车</h2>
{items.map(item => (
<div key={item.id} className="cart-item">
<img src={item.image} alt={item.name} />
<div>
<h3>{item.name}</h3>
<p>${item.price}</p>
</div>
<input
type="number"
value={item.quantity}
onChange={(e) => updateQuantity(item.id, parseInt(e.target.value))}
/>
<button onClick={() => removeItem(item.id)}>删除</button>
</div>
))}
<div className="cart-total">
<strong>总计: ${total.toFixed(2)}</strong>
</div>
</div>
);
}
总结
选择合适的状态管理方案,可以让购物车功能更加健壮和易维护。