// ============================================================ // BannerCarousel — 首页顶部轮播图 // 使用 useBannerList() Hook 获取数据,组件仅负责渲染 // ============================================================ import { useRef, useMemo } from 'react'; import { Carousel, Skeleton } from 'antd'; import type { CarouselRef } from 'antd/es/carousel'; import { useBannerList } from '@/hooks/use-api'; import type { Banner } from '@/services/modules'; // ---------- 组件 Props ---------- interface BannerCarouselProps { className?: string; } // ---------- 组件 ---------- export function BannerCarousel({ className }: BannerCarouselProps) { const carouselRef = useRef(null); const { data: rawBanners, loading } = useBannerList(); // 过滤 + 排序(纯计算,无副作用) const banners = useMemo(() => { if (!rawBanners) return []; return rawBanners .filter((b) => b.is_active) .filter((b) => b.category === 'banner') .sort((a, b) => a.sort_order - b.sort_order); }, [rawBanners]); // 无数据时不渲染 if (!loading && banners.length === 0) { return null; } // 加载态 — 适配长条比例(2280×90) if (loading) { return (
); } return (
1} > {banners.map((banner) => (
{banner.title}
))}
); }