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

如何将Axios实现的购物车逻辑迁移至useSWR?

解决useSWR迁移后购物车数据不返回的问题

问题分析

你当前的useSWR实现只覆盖了登录用户的部分逻辑,且存在几个关键问题导致数据无法返回:

  1. 未处理访客用户(无token)的购物车流程
  2. 依赖请求的触发条件不匹配原逻辑(原Axios中登录用户POST创建后,GET的URL是apis.create_cart,而非apis.get_cart)
  3. Fetcher函数未正确绑定依赖(token变化时未重新触发请求)
  4. 未将最终获取的购物车数据返回给组件使用

修正后的完整实现

以下是完全对齐原Axios逻辑的useSWR版本,包含登录/访客两种场景的处理:

import useSWR from 'swr';
import axios from 'axios';

// 封装通用fetcher,支持POST/GET请求,兼容带token的场景
const fetcher = async ({ url, method = 'GET', headers = {}, data = null }) => {
  try {
    const res = await axios({
      url,
      method,
      headers,
      data
    });
    return res.data;
  } catch (err) {
    throw err.response?.data || err.message;
  }
};

export function useCart(logged, token, apis) {
  // --------------------------
  // 登录用户逻辑:先创建购物车,再获取购物车数据
  // --------------------------
  const { data: createCartRes, error: createCartErr } = useSWR(
    logged && token ? { url: apis.create_cart, method: 'POST', headers: { Authorization: `Bearer ${token}` } } : null,
    fetcher
  );

  const { data: cartData, error: getCartErr } = useSWR(
    // 仅当创建购物车请求完成后,才触发获取请求
    createCartRes && logged && token ? { url: apis.create_cart, headers: { Authorization: `Bearer ${token}` } } : null,
    fetcher
  );

  // --------------------------
  // 访客用户逻辑:处理guest_cart_id
  // --------------------------
  const guestCartId = typeof window !== 'undefined' ? window.localStorage.getItem('guest_cart_id') : null;

  // 创建访客购物车(仅当无guestCartId时触发)
  const { data: createGuestCartRes, error: createGuestCartErr } = useSWR(
    !logged && !token && !guestCartId ? { url: apis.create_guest_cart, method: 'POST' } : null,
    fetcher,
    {
      onSuccess: (data) => {
        // 创建成功后存入localStorage
        if (typeof window !== 'undefined') {
          window.localStorage.setItem('guest_cart_id', data);
        }
      }
    }
  );

  // 获取访客购物车数据
  const targetGuestCartId = createGuestCartRes || guestCartId;
  const { data: guestCartData, error: getGuestCartErr } = useSWR(
    !logged && !token && targetGuestCartId ? { url: `${apis.get_guest_cart}/${targetGuestCartId}/items` } : null,
    fetcher
  );

  // 合并两种场景的最终数据
  const finalCartData = logged ? cartData : guestCartData;
  const finalError = createCartErr || getCartErr || createGuestCartErr || getGuestCartErr;
  const isLoading = !finalCartData && !finalError;

  return {
    cart: finalCartData,
    isLoading,
    error: finalError
  };
}

关键修正点说明

  1. 统一Fetcher:封装支持POST/GET的通用fetcher,避免重复代码,同时兼容Axios(和原实现一致,降低迁移成本)
  2. 依赖请求触发:登录用户的获取购物车请求,仅在createCartRes存在时触发,确保先完成创建操作
  3. 访客逻辑补全:完整实现访客购物车的创建、存储、获取流程,和原Axios逻辑对齐
  4. 数据合并返回:根据logged状态返回对应场景的购物车数据,同时提供loading和error状态供组件使用
  5. SSR兼容:添加typeof window !== 'undefined'判断,避免在服务端渲染时访问localStorage报错

使用方式

在组件中直接调用该hook即可:

const { cart, isLoading, error } = useCart(logged, token, apis);

if (isLoading) return <div>加载中...</div>;
if (error) return <div>加载失败:{error.message}</div>;

// 使用cart数据
return <div>购物车商品:{cart?.length || 0}件</div>;

内容的提问来源于stack exchange,提问作者Mohammed Ismail

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 05:05:21