购物车状态管理最佳实践

Jan 30, 2026160 次浏览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>
  );
}

总结

选择合适的状态管理方案,可以让购物车功能更加健壮和易维护。

解锁完整内容

查看完整教程、源码链接和配置脚本

$5.99一次性付费
永久访问完整内容
包含源码链接和配置脚本
详细的踩坑指南

支付后,解锁链接将发送到此邮箱

已有账号?登录后购买可在用户中心查看