'use client';
import { useState, useEffect, useRef, useCallback, useMemo } from 'react';
import { Swiper, SwiperSlide } from "swiper/react";
import { Navigation, Pagination, Thumbs, FreeMode } from "swiper/modules";
// 导入Swiper样式
import "swiper/css";
import "swiper/css/navigation";
import "swiper/css/pagination";
import "swiper/css/thumbs";
import "swiper/css/free-mode";
const ProductImageGallery = ({ data }) => {
const [currentImageIndex, setCurrentImageIndex] = useState(0);
const [thumbsSwiper, setThumbsSwiper] = useState(null);
const thumbsSwiperRef = useRef(null);
// 如果没有attachments,不显示组件
if (!data?.attachments || data.attachments.length === 0) {
return null;
}
// 使用useMemo优化主图索引计算
const mainImageIndex = useMemo(() => {
if (!data.image) return 0;
const mainImageIndex = data.attachments.findIndex(
attachment => attachment.file_url === data.image
);
return mainImageIndex >= 0 ? mainImageIndex : 0;
}, [data.image, data.attachments]);
// 使用useMemo优化当前图片URL
const currentImage = useMemo(() => {
return data.attachments[currentImageIndex]?.file_url || data.attachments[0]?.file_url;
}, [data.attachments, currentImageIndex]);
// 使用useCallback优化缩略图滚动函数
const scrollThumbnailToIndex = useCallback((index) => {
if (thumbsSwiperRef.current?.swiper) {
try {
const swiper = thumbsSwiperRef.current.swiper;
if (index === 0) {
// 第一张图片,滚动到最左侧
swiper.scrollTo(0, 300);
} else {
// 其他图片使用原有的slideTo方法,保持正常滚动
swiper.slideTo(index, 300);
}
} catch (error) {
// 静默处理错误
}
}
}, []);
// 使用useCallback优化主图切换函数
const changeMainImage = useCallback((direction) => {
if (data.attachments.length <= 1) return;
let newIndex;
if (direction === 'next') {
newIndex = (currentImageIndex + 1) % data.attachments.length;
} else {
newIndex = (currentImageIndex - 1 + data.attachments.length) % data.attachments.length;
}
setCurrentImageIndex(newIndex);
// 自动滚动缩略图到对应位置
setTimeout(() => {
scrollThumbnailToIndex(newIndex);
}, 100);
}, [currentImageIndex, data.attachments.length, scrollThumbnailToIndex]);
// 使用useCallback优化按索引切换主图函数
const changeMainImageByIndex = useCallback((index) => {
setCurrentImageIndex(index);
// 智能滚动缩略图到可见区域
setTimeout(() => {
scrollThumbnailToIndex(index);
}, 100);
}, [scrollThumbnailToIndex]);
// 初始化当前索引为主图索引
useEffect(() => {
setCurrentImageIndex(mainImageIndex);
}, [mainImageIndex]);
// 键盘导航支持 - 使用useCallback优化
const handleKeyDown = useCallback((event) => {
if (data.attachments.length <= 1) return;
switch (event.key) {
case 'ArrowLeft':
event.preventDefault();
changeMainImage('prev');
break;
case 'ArrowRight':
event.preventDefault();
changeMainImage('next');
break;
case 'Home':
event.preventDefault();
setCurrentImageIndex(0);
setTimeout(() => scrollThumbnailToIndex(0), 100);
break;
case 'End':
event.preventDefault();
setCurrentImageIndex(data.attachments.length - 1);
setTimeout(() => scrollThumbnailToIndex(data.attachments.length - 1), 100);
break;
default:
break;
}
}, [data.attachments.length, changeMainImage, scrollThumbnailToIndex]);
useEffect(() => {
document.addEventListener('keydown', handleKeyDown);
return () => {
document.removeEventListener('keydown', handleKeyDown);
};
}, [handleKeyDown]);
// 使用useMemo优化缩略图渲染
const thumbnailSlides = useMemo(() => {
return data.attachments.map((attachment, index) => (
{
e.target.style.display = 'none';
}}
/>
{/* 缩略图加载状态指示 */}