超详细教程:使用React实现动态轮播图

前言

轮播组件是常见的一种方式,用来展示图像、信息或者是广告。我们可以使用React来创建一个轮播组件,并且利用其中的State和effect Hook来创建一款动态的、可以自动播放的轮播组件。

效果

轮播组件会展示一个平铺的图片列表。在图片列表下方是一组小圆点,每个小圆点对应一个图片。当一个新的图片显示时,相对应的小圆点会高亮。组件会每隔一段时间自动切换图片,并且当它切换到最后一张图片后,会继续切回第一张图片。

原理分析

轮播组件的实现依赖于React的**useState useEffect**这两个Hook。

  1. 我们首先通过**useState创建一个 index变量以及一个 setIndex函数。 index**记录了我们当前展示图片的位置。
  2. 下面我们会创建一个名为**list**的变量,它会把图片数组中第一张图片复制一份添加到数组末尾。
  3. 接下来我们在**useEffect中设置一个定时任务,每隔2秒钟更新一次 index**的值,等于在每两秒钟播放下一张图片。
  4. 最后,我们根据**index的值,来计算需要平移的比例,然后定义一个 transform** CSS属性,此步骤定义了图片滚动所需要的动画效果。

代码实现

  1. 首先,我们导入所需的模块以及定义图片数据。
jsx 复制代码
import React, { useState } from "react";
import classnames from "classnames";
import "./index.less";

const dataSource = [
  {
    picture:
      "<https://cdn.fmlg1688.cn/build-material/3c76b0a215c64baebded1a690e1ff989.blob>",
    title: "是怎么做出来的",
  },
  {
    picture:
      "<https://cdn.fmlg1688.cn/build-material/image/b3528a0b59f34e32aa4aae4652bee76f.jpeg>",
    title: "成功案例",
  },
  {
    picture:
      "<https://cdn.fmlg1688.cn/build-material/3c76b0a215c64baebded1a690e1ff989.blob>",
    title: "仿木栏杆-03",
  },
];
  1. 然后实现轮播组件的代码:

    export default function Carousel() {
    const [index, setIndex] = useState(0);
    const carouselRef = useRef<HTMLDivElement>(null);

    const list = useMemo(() => {
    return [...dataSource, dataSource[0]];
    }, [dataSource]);

    useEffect(() => {
    const goNext = () => {
    setTimeout(() => {
    if (index + 1 === list.length) {
    if (carouselRef.current?.style) {
    carouselRef.current.style.transform = "translateX(0%)";
    }
    setIndex(0);
    } else {
    setIndex(index + 1);
    if (index + 1 === list.length - 1) {
    setTimeout(() => {
    setIndex(0);
    }, 300);
    }
    }
    // setIndex((inx) => {
    // if (inx + 1 === list.length) {
    // return 0;
    // } else {
    // if (inx + 1 === list.length) {
    // goNext();
    // }
    // ret
    // });
    }, 2000);
    };
    goNext();
    }, [index]);

    console.log("index:", index);

    return (


    <div
    ref={carouselRef}
    className="carousel"
    style={{
    width: ${100 * list.length}%,
    transform: translateX(-${(100 / list.length) * index}%),
    transition: 0 === index ? `` : "transform 0.3s",
    }}
    >
    {list.map((data) => {
    return (



    );
    })}


      {dataSource.map((data, inx) => {
      return (
      <li
      className={classnames("dot-item", {
      "dot-item--active": index === inx,
      })}
      >
      );
      })}


);
}

export default function Carousel() {
const [index, setIndex] = useState(0);
const carouselRef = useRef<HTMLDivElement>(null);

const list = useMemo(() => {
return [...dataSource, dataSource[0]];
}, [dataSource]);

useEffect(() => {
const goNext = () => {
setTimeout(() => {
if (index + 1 === list.length) {
if (carouselRef.current?.style) {
carouselRef.current.style.transform = "translateX(0%)";
}
setIndex(0);
} else {
setIndex(index + 1);
if (index + 1 === list.length - 1) {
setTimeout(() => {
setIndex(0);
}, 300);
}
}
}, 2000);
};
goNext();
}, [index]);

console.log("index:", index);

return (


<div
ref={carouselRef}
className="carousel"
style={{
width: ${100 * list.length}%,
transform: translateX(-${(100 / list.length) * index}%),
transition: 0 === index ? `` : "transform 0.3s",
}}
>
{list.map((data) => {
return (



);
})}


    {dataSource.map((data, inx) => {
    return (
    <li
    className={classnames("dot-item", {
    "dot-item--active": index === inx,
    })}
    >
    );
    })}


);
}

在这个组件中:

  • 我们定义了一个React引用**carouselRef**,通过这个引用我们可以获取到对应渲染的DOM对象。
  • 在每2秒钟,我们通过**goNext函数来触发轮播图的切换。有一个特别的处理,当轮播切换到复制的第一张图片时,改变 index**到0并且立即清除过渡效果,使得轮播图看起来像是循环播放的。
  • 当创建轮播组件的HTML部分时,我们基于**index值增加 transform transition**样式,通过CSS动画实现了轮播的滚动效果。
  • 最后我们定义了一个小圆点列表,它的作用是表示当前显示的是哪张图片。小圆点的数量等于图片的数量,但是并不包括复制的第一张图片。哪个小圆点处于活动状态是基于**index**值确定的。

总结

以上就是通过React实现轮播图的方法。这个轮播图基于React的**useState useEffect实现,利用了 transform transition**来呈现滑动的动画效果。

上一篇:设计模式——观察者模式
下一篇:React中对UI组件化的步骤和设计原理
相关推荐
gqkmiss28 分钟前
Chrome 浏览器插件获取网页 iframe 中的 window 对象
前端·chrome·iframe·postmessage·chrome 插件
m0_748247553 小时前
Web 应用项目开发全流程解析与实战经验分享
开发语言·前端·php
m0_748255023 小时前
前端常用算法集合
前端·算法
真的很上进3 小时前
如何借助 Babel+TS+ESLint 构建现代 JS 工程环境?
java·前端·javascript·css·react.js·vue·html
web130933203983 小时前
vue elementUI form组件动态添加el-form-item并且动态添加rules必填项校验方法
前端·vue.js·elementui
NiNg_1_2344 小时前
Echarts连接数据库,实时绘制图表详解
前端·数据库·echarts
如若1234 小时前
对文件内的文件名生成目录,方便查阅
java·前端·python
滚雪球~5 小时前
npm error code ETIMEDOUT
前端·npm·node.js
沙漏无语5 小时前
npm : 无法加载文件 D:\Nodejs\node_global\npm.ps1,因为在此系统上禁止运行脚本
前端·npm·node.js
supermapsupport5 小时前
iClient3D for Cesium在Vue中快速实现场景卷帘
前端·vue.js·3d·cesium·supermap