Next.js中用Zustand实现购物车时getState属性不存在错误解决
Zustand在Next.js中购物车总数量统计问题解决
问题与错误信息
在Next.js中使用Zustand实现购物车功能时,添加商品或点击增减按钮统计购物车总数量时触发报错。代码中使用const state = set.getState();引发如下类型错误:
Property 'getState' does not exist on type '(partial: CartState | Partial
| ((state: CartState) => CartState | Partial ), replace?: boolean | undefined) => void'.
错误原因
Zustand的set函数仅负责修改状态,并不提供getState方法。要获取当前store的状态,需要使用创建store时回调函数提供的get参数。
解决方案
方案1:使用get函数获取状态并计算总数量
在创建store时,从回调参数中解构出get,然后在getTotalItems方法中调用get()获取当前状态并计算总数量:
修改后的完整cart.ts代码:
import create from 'zustand'; interface CartState { items: { id: number; name: string; price: number; quantity: number }[]; addToCart: (item: { id: number; name: string; price: number }) => void; removeFromCart: (itemId: number) => void; increaseQuantity: (itemId: number) => void; decreaseQuantity: (itemId: number) => void; getTotalItems: () => number; } export const useCart = create<CartState>((set, get) => ({ items: [], addToCart: (item) => set((state) => ({ items: [...state.items, { ...item, quantity: 1 }] })), removeFromCart: (itemId) => set((state) => ({ items: state.items.filter((item) => item.id !== itemId) })), increaseQuantity: (itemId) => set((state) => ({ items: state.items.map((item) => item.id === itemId ? { ...item, quantity: item.quantity + 1 } : item ), })), decreaseQuantity: (itemId) => set((state) => ({ items: state.items.map((item) => item.id === itemId ? { ...item, quantity: Math.max(1, item.quantity - 1) } : item ), })), getTotalItems: () => { const state = get(); return state.items.reduce((acc, item) => acc + item.quantity, 0); }, }));
方案2:维护派生状态(性能更优)
直接在store中维护totalItems字段,每次修改items时同步更新总数量,组件可直接订阅该值,避免重复计算:
import create from 'zustand'; interface CartState { items: { id: number; name: string; price: number; quantity: number }[]; totalItems: number; addToCart: (item: { id: number; name: string; price: number }) => void; removeFromCart: (itemId: number) => void; increaseQuantity: (itemId: number) => void; decreaseQuantity: (itemId: number) => void; } const calculateTotalItems = (items: CartState['items']) => { return items.reduce((acc, item) => acc + item.quantity, 0); }; export const useCart = create<CartState>((set) => ({ items: [], totalItems: 0, addToCart: (item) => set((state) => { const newItems = [...state.items, { ...item, quantity: 1 }]; return { items: newItems, totalItems: calculateTotalItems(newItems) }; }), removeFromCart: (itemId) => set((state) => { const newItems = state.items.filter((item) => item.id !== itemId); return { items: newItems, totalItems: calculateTotalItems(newItems) }; }), increaseQuantity: (itemId) => set((state) => { const newItems = state.items.map((item) => item.id === itemId ? { ...item, quantity: item.quantity + 1 } : item ); return { items: newItems, totalItems: calculateTotalItems(newItems) }; }), decreaseQuantity: (itemId) => set((state) => { const newItems = state.items.map((item) => item.id === itemId ? { ...item, quantity: Math.max(1, item.quantity - 1) } : item ); return { items: newItems, totalItems: calculateTotalItems(newItems) }; }), }));
组件中直接使用:
const { totalItems } = useCart();
方案选择建议
- 方案1适合偶尔需要计算总数量的场景,每次调用
getTotalItems会重新计算 - 方案2将总数量作为状态维护,避免重复计算,性能更优,适合频繁展示总数量的场景
内容的提问来源于stack exchange,提问作者fagbemi ayodele
相关产品推荐
相关产品推荐

