You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 11:55:31