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

React滑块组件Inner Slider循环序列异常的修复方案咨询

解决方案

问题核心是Inner Slider仅依赖原数组做滑动偏移,导致元素被移出容器后无法循环补充。要实现预期的循环序列,需要通过扩展数据源+无缝状态重置来实现。

关键修改点

  • 复制图片数组,让Inner Slider的数据源变为[...image, ...image],保证滑动时能衔接后续元素
  • 修正偏移计算逻辑,确保每次滑动都显示连续的三张图
  • 优化定时器逻辑,避免无限触发和内存泄漏
  • 当current达到原数组长度时,无缝重置状态,保持轮播连续性

修改后的完整代码

import React, { useEffect, useState } from "react";
import { motion, AnimatePresence } from "framer-motion";
const image = [
  { 
    banner: "https://image.tmdb.org/t/p/original/sRLC052ieEzkQs9dEtPMfFxYkej.jpg",
    poster: "https://image.tmdb.org/t/p/original/ui4DrH1cKk2vkHshcUcGt2lKxCm.jpg"
  },
  { 
    banner: "https://image.tmdb.org/t/p/original/4HodYYKEIsGOdinkGi2Ucz6X9i0.jpg",
    poster: "https://image.tmdb.org/t/p/original/ui4DrH1cKk2vkHshcUcGt2lKxCm.jpg"
  },
  { 
    banner: "https://image.tmdb.org/t/p/original/1jITxVJhkiFJuQuj8NcPLmDNtJg.jpg",
    poster: "https://image.tmdb.org/t/p/original/qjhahNLSZ705B5JP92YMEYPocPz.jpg"
  }
];

export default function Carousel() {
  const [current, setCurrent] = useState(0);
  const [isTransitioning, setIsTransitioning] = useState(false);
  const imageLength = image.length;

  const nextImage = function () {
    if (isTransitioning) return;
    
    if (current === imageLength - 1) {
      // 滑到原数组末尾时,完成动画后无缝重置状态
      setIsTransitioning(true);
      setTimeout(() => {
        setCurrent(0);
        setIsTransitioning(false);
      }, 300); // 匹配动画过渡时长
    } else {
      setCurrent(prev => prev + 1);
    }
  };

  useEffect(() => {
    const timer = setTimeout(() => {
      nextImage();
    }, 2000);
    
    return () => clearTimeout(timer); // 清理定时器,避免内存泄漏
  }, [current, isTransitioning]);

  const variants = {
    initial: {
      x: 1000,
      opacity: 0,
    },
    animate: {
      x: 0,
      opacity: 1,
      transition: {
        x: { type: "spring", stiffness: 300, damping: 30 },
        opacity: { duration: 0.2 },
      },
    },
    exit: {
      x: -1000,
      opacity: 0,
      transition: {
        x: { type: "spring", stiffness: 300, damping: 30 },
        opacity: { duration: 0.2 },
      },
    },
  };

  return (
    <div className="w-full h-[550px] overflow-hidden relative">
      <AnimatePresence initial={false} >
        <motion.img
          variants={variants}
          animate="animate"
          initial="initial"
          exit="exit"
          alt="slides"
          key={image[current]?.banner}
          className="slides z-20 absolute inset-0 w-full h-full object-cover"
          src={image[current]?.banner}
        />

        <div className="absolute w-[40%] h-auto overflow-hidden justify-center  top-1/2 translate-y-[-50%] gap-4 m-auto flex right-8 z-40" >
          {/* Inner Slider - 用双数组实现循环展示 */}
          {[...image, ...image].map((items, index) => (
            <motion.img 
              src={items?.poster} 
              key={index} 
              className="w-[30%] object-cover" 
              alt="" 
              animate={{ 
                x: isTransitioning ? 0 : `calc(-${current * 100}% - ${current}rem)`,
                transition: isTransitioning ? { duration: 0 } : {}
              }}
            />
          ))}
        </div>
        
      </AnimatePresence>
       
    </div>
  );
}

效果说明

  1. 双数组数据源:[...image, ...image]让Inner Slider拥有6个元素,滑动到原数组末尾时,复制的元素会衔接上来,视觉上形成[img1,img2,img3]→[img2,img3,img1]→[img3,img1,img2]的循环序列。
  2. 无缝重置:当current到达原数组最后一位时,先完成滑动动画,再瞬间重置current为0并关闭过渡动画,避免出现跳变。
  3. 定时器优化:添加清理函数防止内存泄漏,依赖current和isTransitioning确保轮播节奏稳定。

内容的提问来源于stack exchange,提问作者Arnab Mukherjee

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 06:32:36