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

如何在Next.js中实现购物车/结账页面的无刷新更新?

无刷新更新Saleor购物车状态的实现方案

针对你用Saleor无头后端+Next.js starter遇到的购物车刷新闪烁问题,核心思路是用客户端缓存/状态管理替代页面刷新,下面是两种可落地的实现方式:

1. 用SWR管理购物车数据(推荐,适配Next.js生态)

Saleor官方starter大多集成了SWR,直接基于它改造就能快速实现无刷新更新:

封装购物车请求Hook

先写一个复用的Hook来获取和更新购物车数据:

import useSWR from 'swr';
import { getCheckout } from '../lib/api'; // 你项目里调用Saleor API获取Checkout的函数
import { getCookie } from '../lib/cookies'; // 自定义的cookie读取工具

export function useCheckout() {
  // 用SWR缓存购物车数据,key设为固定值标识购物车请求
  const { data: checkout, mutate } = useSWR('checkout-data', async () => {
    const checkoutId = getCookie('checkoutId');
    if (!checkoutId) return null;
    return await getCheckout(checkoutId);
  });

  return { checkout, refreshCheckout: mutate };
}

这里的mutate是SWR提供的手动更新缓存方法,调用后会重新拉取最新的Checkout数据,且只更新依赖该数据的组件。

修改AddToCart组件

在add-to-cart.tsx里,完成添加商品的API调用后,直接触发缓存更新:

import { useCheckout } from '../hooks/useCheckout';
import { addItemToCheckout } from '../lib/api'; // 调用Saleor API添加商品的函数

export default function AddToCart({ variantId }) {
  const { refreshCheckout } = useCheckout();

  const handleAdd = async () => {
    const checkoutId = getCookie('checkoutId');
    // 调用Saleor API添加商品到购物车
    await addItemToCheckout(checkoutId, variantId, 1);
    // 手动更新购物车缓存,触发组件重渲染
    await refreshCheckout();
  };

  return <button onClick={handleAdd}>加入购物车</button>;
}

修改Cart组件渲染逻辑

在cart.tsx里,直接用Hook返回的checkout数据渲染即可,不用再依赖服务器端渲染的静态数据:

import { useCheckout } from '../hooks/useCheckout';

export default function Cart() {
  const { checkout } = useCheckout();

  if (!checkout) return <div>购物车为空</div>;

  return (
    <div className="cart-container">
      <h3>我的购物车</h3>
      {checkout.lines.map(line => (
        <div key={line.id} className="cart-item">
          <span>{line.product.name}</span>
          <span>数量: {line.quantity}</span>
          <span>小计: {line.totalPrice.gross.amount} {line.totalPrice.gross.currency}</span>
        </div>
      ))}
      <div className="cart-total">
        总计: {checkout.totalPrice.gross.amount} {checkout.totalPrice.gross.currency}
      </div>
    </div>
  );
}

2. 用React Context自定义状态管理

如果不想用SWR,也可以自己写Context来维护购物车状态:

创建Checkout Context

// context/CheckoutContext.tsx
import { createContext, useContext, useState, useEffect } from 'react';
import { getCheckout } from '../lib/api';
import { getCookie } from '../lib/cookies';

const CheckoutContext = createContext({
  checkout: null,
  refreshCheckout: async () => {}
});

export function CheckoutProvider({ children }) {
  const [checkout, setCheckout] = useState(null);

  // 初始化时加载购物车数据
  useEffect(() => {
    const fetchInitCheckout = async () => {
      const checkoutId = getCookie('checkoutId');
      if (checkoutId) {
        const data = await getCheckout(checkoutId);
        setCheckout(data);
      }
    };
    fetchInitCheckout();
  }, []);

  // 手动刷新购物车的方法
  const refreshCheckout = async () => {
    const checkoutId = getCookie('checkoutId');
    if (checkoutId) {
      const data = await getCheckout(checkoutId);
      setCheckout(data);
    }
  };

  return (
    <CheckoutContext.Provider value={{ checkout, refreshCheckout }}>
      {children}
    </CheckoutContext.Provider>
  );
}

// 自定义Hook方便组件调用
export const useCheckout = () => useContext(CheckoutContext);

记得在_app.tsx里用CheckoutProvider包裹所有页面组件:

import { CheckoutProvider } from '../context/CheckoutContext';

export default function App({ Component, pageProps }) {
  return (
    <CheckoutProvider>
      <Component {...pageProps} />
    </CheckoutProvider>
  );
}

改造AddToCart和Cart组件

和SWR的方式类似,在add-to-cart.tsx里调用API后触发refreshCheckout,cart.tsx直接用Context里的checkout数据渲染即可,代码逻辑和上面SWR版本的组件一致,只是换了Hook来源。

关键注意点

  • 确保你的API函数(比如addItemToCheckout、getCheckout)能正确和Saleor的GraphQL API交互,添加/删除商品后,getCheckout能拿到最新的购物车状态。
  • 删除商品的逻辑和添加完全一致:调用删除API后,触发refreshCheckout或mutate即可。
  • 如果用SWR,可以配置revalidateOnFocus: true,确保用户切回页面时自动同步最新购物车状态。

内容的提问来源于stack exchange,提问作者Jonathan Franzen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 16:05:36