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

news2024/12/23 23:08:47

前言

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

效果

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

原理分析

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

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

代码实现

  1. 首先,我们导入所需的模块以及定义图片数据。
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 className="carousel-container">
      <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 (
            <div className="carousel-item">
              <img src={data.picture} />
            </div>
          );
        })}
      </div>
      <ul className="dot">
        {dataSource.map((data, inx) => {
          return (
            <li
              className={classnames("dot-item", {
                "dot-item--active": index === inx,
              })}
            ></li>
          );
        })}
      </ul>
    </div>
  );
}

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 className="carousel-container">
      <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 (
            <div className="carousel-item">
              <img src={data.picture} />
            </div>
          );
        })}
      </div>
      <ul className="dot">
        {dataSource.map((data, inx) => {
          return (
            <li
              className={classnames("dot-item", {
                "dot-item--active": index === inx,
              })}
            ></li>
          );
        })}
      </ul>
    </div>
  );
}

在这个组件中:

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

总结

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1310818.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

java定位系统源码,UWB技术的无线定位系统源码

UWB技术是一种传输速率高&#xff0c;发射功率较低&#xff0c;穿透能力较强并且是基于极窄脉冲的无线技术。UWB最优的应用环境是室内或者相对密闭的空间&#xff0c;有着厘米级的定位精度&#xff0c;不仅可以非常精准地进行位置跟踪&#xff0c;还可以快速地进行数据传输。 智…

基于亚马逊云科技新功能:Amazon SageMaker Canvas无代码机器学习—以构建货物的交付状态检测模型实战为例深度剖析以突显其特性

授权说明&#xff1a;本篇文章授权活动官方亚马逊云科技文章转发、改写权&#xff0c;包括不限于在亚马逊云科技开发者社区、 知乎、自媒体平台、第三方开发者媒体等亚马逊云科技官方渠道。 目录 &#x1f680;一. Amazon SageMaker &#x1f50e;1.1 新功能发布&#xff1a;A…

消息通知(Notification)/用户触达系统设计

近年来&#xff0c;通知功能已经成为许多应用程序中突出的特性。构建一个能每天发送数百万通知的可扩展系统绝非易事。这正是为什么我觉得有必要记录我在这方面踩坑之路。也叫用户触达系统。 完成这项任务要求对通知生态系统有深刻的理解&#xff0c;否则需求很容易变得模糊和…

系列十五、Redis面试题集锦

一、Redis面试题集锦 1.1、Redis到底是单线程还是多线程 Redis6.0版本之前的单线程指的是其网络IO和键值对读写是由一个线程完成的&#xff1b; Redis6.0引入的多线程指的是网络请求过程采用了多线程&#xff0c;而键值对读写命令仍然是单线程的&#xff0c;所以多线程环境下&…

MITO-ID®线粒体膜电位检测试剂盒

线粒体膜电位&#xff08;Mitochondrial Membrane Potential,MMP&#xff09;是判定细胞健康程度、线粒体膜通透性和细胞凋亡的一个重要指标&#xff0c;MMP的丧失通常与细胞凋亡的早期阶段有关。评估线粒体功能状态的基于细胞的检测方法正在成为阐明线粒体活动在药物诱导毒性、…

记录Oracle Exadata X8M-2 存储服务器告警灯亮的处理过程(/SYS/MB/P0PCIE7)

文章目录 概要调查流程处理方式&#xff1a; 概要 现场服务器告警灯亮&#xff0c;其他服务器正常&#xff0c;磁盘灯正常&#xff0c;所以从整体来看应是内部部件抛出的异常问题&#xff0c;需要登录机器确认&#xff1a; 调查流程 通过ILOM web界面查看服务器状态进行信息…

Java代码实现简易版王者荣耀

一.主窗口类 package com.sxt;import com.sxt.beast.Beast;import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.io.File; import java.util.Arra…

拓展 Amazon S3 技术边界:Amazon S3 Express One Zone 的创新之路

授权说明&#xff1a;本篇文章授权活动官方亚马逊云科技文章转发、改写权&#xff0c;包括不限于在 亚马逊云科技开发者社区, 知乎&#xff0c;自媒体平台&#xff0c;第三方开发者媒体等亚马逊云科技官方渠道 自 Amazon S3 服务推出以来&#xff0c;一直是全球各行各业数百万客…

Linux基本开发工具

编译器和自动化构建工具 一、编译器——gcc、g1. 安装 gcc/g2. 使用3. 链接库4. 拓展命令&#xff1a;od/file/ldd/readelf 二、自动化构建项目——make、makefile1. 介绍2. 使用例子touch——change file timestampsstat——display file or file system status修改时间 .PHON…

SpringBoot2—开发实用篇1

目录 热部署 手动启动热部署 自动启动热部署 热部署范围配置 关闭热部署 配置高级 测试 热部署 什么是热部署&#xff1f;简单说就是你程序改了&#xff0c;现在要重新启动服务器&#xff0c;嫌麻烦&#xff1f;不用重启&#xff0c;服务器会自己悄悄的把更新后的程序给…

大模型时代-怎么正确的开发和使用AI模型

一、背景 大模型的概念已经经过了一年的发酵&#xff0c;大家也渐渐的冷静下来了。一开始大家很兴奋&#xff0c;感觉新的时代要来了&#xff0c;然后就是疯狂&#xff0c;再就是都各自找各自公司的东西怎么与大模型沾点边&#xff0c;要不然今年玩不下去了&#xff0c;就要落伍…

数据结构和算法 - 数组

1、数组 1.1 简介 什么是数组&#xff1f; 他优缺点是什么&#xff1f;具体应用有哪些&#xff1f; 「数组 array」是一种基于顺序存储的线性数据结构&#xff0c;其将相同类型的元素存储在连续的内存空间中。我们将元素在数组中的位置称为该元素的「索引 index」。 如图&…

生产问题排查思路

生产上有用户反映&#xff0c;登录之后页面信息加载不出来&#xff0c;请求响应时间慢等。 下图为生产上一个请求在网关上面的流程&#xff1a; 因为我们生产上&#xff0c;有一张异常信息记录表&#xff0c;第一时间查询了上面是否有最近的异常记录。发现了一点&#xff0c;是…

vue整个页面可以拖拽导入文件

效果图 原理与源码 我们这里的思路是用ant组件库的upload组件&#xff0c;就是如下这个 用这个包裹住所有页面&#xff0c;你可以是包裹住App.vue&#xff0c;或者是你的homepage。但是这个涉及到一个问题&#xff0c;就是我们现在确实是可以拖拽导进来文件了&#xff0c;但是…

【Stm32-F407】Keil uVision5 下新建工程

①双击鼠标左键打开Keil uVision5&#xff0c;选择 Project 下的 New uVision Project &#xff1b; ②在期望的文件夹下创建一个工程&#xff0c;并按如下要求操作&#xff1b; ③添加文件类型&#xff0c;按如下要求操作 ④如有需要可添加相关启动文件在工程文件夹下并添加到…

WEB 3D技术 以vue3+vite环境为例 讲解vue项目中使用three

上文 WEB 3D 技术&#xff0c;通过node环境创建一个three案例 中 我们打造了自己的第一个Web 3D界面 那么 今天 我们就来结合vue来开发我们的3D界面 这里 我们先创建一个文件夹 作为文件目录 千万不要放C盘 我们 依旧是在终端执行命令 npm init vitelatest输入一下项目名称 …

[GWCTF 2019]我有一个数据库1

提示 信息收集phpmyadmin的版本漏洞 这里看起来不像是加密应该是编码错误 这里访问robots.txt 直接把phpinfo.php放出来了 这里能看到它所有的信息 这里并没有能找到可控点 用dirsearch扫了一遍 ####注意扫描buuctf的题需要控制扫描速度&#xff0c;每一秒只能扫10个多一个都…

vue2 echarts不同角色多个类型数据的柱状图

前端代码&#xff1a; 先按照echarts插件。在页面里引用 import * as echarts from "echarts";设置div <div style"width:100%;height:250px;margin-top: 4px;" id"addressChart"></div>方法: addressEcharts() {const option {g…

vue 将后端返回的二进制流进行处理并实现下载

什么是二进制流文件&#xff1f; 二进制文件是一种计算机文件格式&#xff0c;它的数据以二进制形式存储&#xff0c;与文本文件不同。二进制文件可以包含任意类型的数据&#xff0c;例如图像、音频、视频、可执行文件、压缩文件等&#xff0c;而文本文件则仅仅包含 ASCII 码或…

<JavaEE> 网络编程 -- 网络通信基础(协议和协议分层、数据封装和分用)

目录 一、IP地址 1&#xff09;IP地址的概念 2&#xff09;IP地址的格式 二、端口号 1&#xff09;端口号的概念 2&#xff09;端口号的格式 3&#xff09;什么是知名端口号&#xff1f; 三、协议 1&#xff09;协议的概念 2&#xff09;协议的作用 3&#xff09;TC…