1. 基于useStore的状态管理架构设计
- 创建独立的store文件:为每个主要模块(商品展示、购物车、用户订单)创建单独的
useStore
。例如,useProductStore.ts
、useCartStore.ts
、useOrderStore.ts
。
// useProductStore.ts
import { create } from 'zustand';
interface Product {
id: string;
name: string;
price: number;
// 其他商品相关属性
}
interface ProductStore {
products: Product[];
fetchProducts: () => void;
// 其他商品操作方法
}
const useProductStore = create<ProductStore>((set) => ({
products: [],
fetchProducts: async () => {
const response = await fetch('/api/products');
const data = await response.json();
set({ products: data });
}
}));
export default useProductStore;
// useCartStore.ts
import { create } from 'zustand';
import useProductStore from './useProductStore';
interface CartItem {
product: Product;
quantity: number;
}
interface CartStore {
cartItems: CartItem[];
addToCart: (productId: string) => void;
removeFromCart: (productId: string) => void;
updateQuantity: (productId: string, quantity: number) => void;
}
const useCartStore = create<CartStore>((set) => ({
cartItems: [],
addToCart: (productId) => {
const product = useProductStore.getState().products.find(p => p.id === productId);
if (product) {
set((state) => {
const existingItem = state.cartItems.find(item => item.product.id === productId);
if (existingItem) {
existingItem.quantity++;
return { cartItems: [...state.cartItems] };
} else {
return { cartItems: [...state.cartItems, { product, quantity: 1 }] };
}
});
}
},
removeFromCart: (productId) => {
set((state) => ({
cartItems: state.cartItems.filter(item => item.product.id!== productId)
}));
},
updateQuantity: (productId, quantity) => {
set((state) => {
const index = state.cartItems.findIndex(item => item.product.id === productId);
if (index!== -1) {
const newCartItems = [...state.cartItems];
newCartItems[index].quantity = quantity;
return { cartItems: newCartItems };
}
return state;
});
}
}));
export default useCartStore;
// useOrderStore.ts
import { create } from 'zustand';
import useCartStore from './useCartStore';
interface Order {
id: string;
items: CartItem[];
totalPrice: number;
// 其他订单相关属性
}
interface OrderStore {
orders: Order[];
placeOrder: () => void;
}
const useOrderStore = create<OrderStore>((set) => ({
orders: [],
placeOrder: () => {
const cartItems = useCartStore.getState().cartItems;
const totalPrice = cartItems.reduce((acc, item) => acc + item.product.price * item.quantity, 0);
const newOrder: Order = {
id: new Date().getTime().toString(),
items: cartItems,
totalPrice
};
set((state) => ({ orders: [...state.orders, newOrder] }));
useCartStore.getState().cartItems = [];
}
}));
export default useOrderStore;
2. 模块状态划分与协同
- 状态划分:
- 商品展示模块:负责管理商品列表数据,如商品的基本信息(名称、价格、图片等)、商品筛选条件等状态。
- 购物车模块:管理购物车中的商品项,包括商品的数量、选中状态等。它依赖商品展示模块获取商品的基本信息。
- 用户订单模块:管理用户的订单数据,包括订单列表、订单详情等。它依赖购物车模块获取下单时的商品信息。
- 协同方式:
- 购物车与商品展示:购物车通过
useProductStore
获取商品信息来填充购物车项。当商品在购物车中的数量、选中状态等发生变化时,购物车状态更新。
- 订单与购物车:订单模块在下单操作时,从购物车获取当前购物车中的商品项,生成订单。下单成功后,清空购物车。
3. 确保状态的一致性和可维护性
- 单一数据源:每个模块的状态都集中在各自的
useStore
中,避免状态分散。例如,商品信息只在 useProductStore
中管理,购物车信息只在 useCartStore
中管理。
- 模块化与封装:每个
useStore
负责管理特定模块的状态和操作,将相关的逻辑封装在一起,提高代码的可维护性。例如,useCartStore
只处理与购物车相关的添加、删除、更新数量等操作。
- 使用中间件和订阅:可以使用 Zustand 提供的中间件,如
zustand-middleware
来处理日志记录、状态持久化等。同时,可以通过订阅机制,在状态变化时执行一些副作用操作,如保存状态到本地存储。
import { create } from 'zustand';
import { devtools, persist } from 'zustand/middleware';
const useCartStore = create(
devtools(
persist((set) => ({
cartItems: [],
addToCart: (productId) => {
// 逻辑不变
},
// 其他方法
}), {
name: 'cart-storage'
})
)
);
4. 高并发操作下保证数据准确性和性能
- 乐观锁:在数据更新时,使用乐观锁机制。例如,在更新商品库存、购物车数量等操作时,每次读取数据时带上版本号,更新时验证版本号是否一致。如果不一致,则重新读取数据并更新。
// 更新商品库存
async function updateProductStock(productId, newStock, version) {
const response = await fetch(`/api/products/${productId}/stock`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ newStock, version })
});
const data = await response.json();
if (response.status === 409) {
// 版本冲突,重新获取数据并更新
const product = await fetchProduct(productId);
updateProductStock(productId, newStock, product.version);
}
return data;
}
- 防抖与节流:对于频繁触发的操作,如购物车数量的实时更新,使用防抖或节流技术。例如,在用户频繁修改购物车数量时,使用防抖函数,在一定时间间隔内只执行一次更新操作,减少不必要的请求。
import { debounce } from 'lodash';
const updateCartQuantityDebounced = debounce((productId, quantity) => {
useCartStore.getState().updateQuantity(productId, quantity);
}, 300);
- 缓存机制:对于一些不经常变化的数据,如商品的基本信息,可以使用缓存。在前端设置本地缓存,减少重复请求服务器的次数。例如,使用
localStorage
或 sessionStorage
缓存商品列表数据,在一定时间内优先从缓存中读取数据。
async function fetchProducts() {
const cachedProducts = localStorage.getItem('products');
if (cachedProducts) {
useProductStore.getState().products = JSON.parse(cachedProducts);
return;
}
const response = await fetch('/api/products');
const data = await response.json();
localStorage.setItem('products', JSON.stringify(data));
useProductStore.getState().products = data;
}