81 lines
2.3 KiB
TypeScript
81 lines
2.3 KiB
TypeScript
/**
|
||
* 竞品对比页面数据获取 Hook
|
||
*
|
||
* 封装品牌列表 + 对比数据的 SWR 请求,替代手动 useState + useEffect 模式。
|
||
* - 品牌列表:mount 时自动获取
|
||
* - 对比数据:依赖 selectedBrandId,为空时暂停请求
|
||
*/
|
||
|
||
import { useState, useCallback } from "react";
|
||
import { useApi } from "./use-api";
|
||
import type { SWRConfiguration } from "swr";
|
||
import type { BrandListResponse, BrandListItem, CompareResponse } from "@/types/brand";
|
||
|
||
export interface UseCompareDataReturn {
|
||
/** 品牌列表 */
|
||
brands: BrandListItem[];
|
||
/** 当前选中的品牌 ID */
|
||
selectedBrandId: string;
|
||
/** 设置选中的品牌 ID */
|
||
setSelectedBrandId: (id: string) => void;
|
||
/** 对比数据 */
|
||
compareData: CompareResponse | undefined;
|
||
/** 是否正在加载(品牌列表或对比数据任一加载中) */
|
||
isLoading: boolean;
|
||
/** 错误信息 */
|
||
error: Error | undefined;
|
||
/** 刷新品牌列表 */
|
||
refreshBrands: () => void;
|
||
/** 刷新对比数据 */
|
||
refreshCompare: () => void;
|
||
}
|
||
|
||
export interface UseCompareDataOptions {
|
||
/** 初始选中的品牌 ID */
|
||
initialBrandId?: string;
|
||
/** SWR 配置(用于测试时禁用重试等) */
|
||
swrOptions?: SWRConfiguration;
|
||
}
|
||
|
||
export function useCompareData(
|
||
options?: UseCompareDataOptions
|
||
): UseCompareDataReturn {
|
||
const initialBrandId = options?.initialBrandId;
|
||
const swrOptions = options?.swrOptions;
|
||
|
||
const [selectedBrandId, setSelectedBrandId] = useState<string>(initialBrandId ?? "");
|
||
|
||
// 品牌列表
|
||
const {
|
||
data: brandsResponse,
|
||
isLoading: brandsLoading,
|
||
error: brandsError,
|
||
refresh: refreshBrands,
|
||
} = useApi<BrandListResponse>("/api/v1/brands/", swrOptions);
|
||
|
||
const brands: BrandListItem[] = brandsResponse?.items ?? [];
|
||
|
||
// 对比数据 — 依赖 selectedBrandId,为空时暂停
|
||
const compareUrl = selectedBrandId ? `/api/v1/brands/${selectedBrandId}/compare` : null;
|
||
const {
|
||
data: compareData,
|
||
isLoading: compareLoading,
|
||
error: compareError,
|
||
refresh: refreshCompare,
|
||
} = useApi<CompareResponse>(compareUrl, swrOptions);
|
||
|
||
const isLoading = brandsLoading || compareLoading;
|
||
const error = brandsError || compareError;
|
||
|
||
return {
|
||
brands,
|
||
selectedBrandId,
|
||
setSelectedBrandId,
|
||
compareData,
|
||
isLoading,
|
||
error,
|
||
refreshBrands,
|
||
refreshCompare,
|
||
};
|
||
}
|