//src/lib/swrFetcher.js
/**
* SWR 请求封装
* 1. 基于 SWR 和 axios 封装的 GET 请求 hook
* 2. 用于执行非 GET 请求(例如登录、提交表单等)的自定义 hook
* 3. 生成唯一的 key,确保相同参数的序列化结果一致
* 4. 使用 json-stable-stringify 来实现稳定的序列化
* 5. 使用 useSWR 和 useSWRMutation 来实现请求和响应的缓存、重验证等特性
* 6. 使用 httpAxios 实例来发起请求
*/
"use client";
import useSWR from "swr";
import useSWRMutation from "swr/mutation";
import stableStringify from "json-stable-stringify";
import httpAxios from "@/lib/httpAxios";
/**
* 根据 URL、HTTP 方法和查询参数生成唯一的 key
* 使用json-stable-stringify 来实现稳定的序列化:确保相同参数的序列化结果一致
* @param {string} url
* @param {string} method
* @param {object} params
* @returns {string}
*/
function generateRequestKey(url, method, params) {
const paramsString = params ? stableStringify(params) : "";
return `${method.toUpperCase()}::${url}::${paramsString}`;
}
/**
* useSwrRequest - 基于 SWR 和 axios 封装的 GET 请求 hook
* 主要用于 GET 请求和数据查询,支持缓存、重验证等特性
*
* @param {object} options - Axios 请求配置,包括 url、method、params、data 等,
* 另外支持 isEnabled(默认 true)控制是否自动发起请求
* @param {object} swrConfig - SWR 的配置项
* @returns {object} SWR 响应对象,额外附加 responseData(即后端 data 字段)和 requestKey
*/
export function useRequest(options, swrConfig = {}) {
const { isEnabled = true, url, method = "GET", params } = options;
const requestKey =
isEnabled && url ? generateRequestKey(url, method, params) : null;
const fetcher = async () => {
const response = await httpAxios.request(options);
return { data: response.data, headers: response.headers };
};
const swrResponse = useSWR(requestKey, fetcher, swrConfig);
return {
...swrResponse,
responseData: swrResponse.data ? swrResponse.data.data : undefined,
headers: swrResponse.data ? swrResponse.data.headers : undefined,
requestKey: requestKey || "",
};
}
/**
* swrMutation - 用于执行非 GET 请求(例如登录、提交表单等)的自定义 hook
* 针对 POST/PUT/DELETE 等非幂等操作,使用 SWR 提供的 mutation 机制,通过手动调用 trigger 发起请求,避免自动缓存和重复请求的问题
*
* @param {string} key - 唯一标识,通常为 URL
* @param {object} defaultOptions - 默认的 axios 请求配置(例如 URL、method 等)
* @param {object} swrMutationConfig - SWR Mutation 的配置项
* @returns {object} 包含 trigger、data、error、isMutating 等字段
*/
export function useMutation(key, defaultOptions = {}, swrMutationConfig = {}) {
const mutationFetcher = async (_, { arg }) => {
// 动态传入的参数与默认配置合并
const requestOptions = { ...defaultOptions, ...arg };
const response = await httpAxios.request(requestOptions);
return { data: response.data, headers: response.headers };
};
return useSWRMutation(key, mutationFetcher, swrMutationConfig);
}
SWR 是一个 React Hooks 库,用于数据获取、缓存和重验证等场景,可以方便地实现数据请求的缓存、重验证等特性。在实际开发中,可以使用 SWR 来简化数据请求的处理,提高开发效率。我们可以通过封装 useRequest 和 useMutation 等自定义 hook 来实现不同类型的请求,从而更好地利用 SWR 的特性。而无论是 GET 请求还是非 GET 请求,都可以通过 SWR 来实现数据请求的缓存、重验证等特性,提高页面性能和用户体验。