React使用定时器自动切换图片

1. 效果展示

在这里插入图片描述

2. 需求分析

最近在学习React框架的时候,做的项目有一个需求就是如何将多张图片依次播放出来,当时的想法是使用轮播图去实现播放,但是这里有一个问题来了:如果我们的图片数量低于20张以下的话效果还是可以的,如果我们图片的数量较多的话,那使用轮播图效率就显得低下,这时我的这个想法就立即pass。
既然,轮播图这种方式不行,有没有其他方法替代呢?这里我到百度和谷歌上找了个遍,终于看到了一种适合我的需求的技术,那就是使用定时器。

2.1 定时器

关于js中定时器我们只需要知道这两个函数就可以:

1)setInterval()

setInterval() :按照指定的周期(以毫秒计)来调用函数或计算表达式。
方法会不停地调用函数,直到 clearInterval() 被调用或窗口被关闭。

2)setTimeout()

在指定的毫秒数后调用函数或计算表达式。

相关知识点可参考:js定时器

2.2 实现思路

上面说了一大堆,就是为了表达自己在碰到这种技术难题的一种解决方法,下面就是开始自己如何实现。

首先,我自己参考了文献1里面的那片文章,里面提到了使用JS定时器实现图片切换,但是看了下觉得思路还是可以的,但是因为自己JS学的不多里面使用到的window.onload = function()直接用到React中出现了一些语法不同的问题,自己网上找了些许没搞明白,所以暂时汲取它的思路,看看网上还有其他的关于React的版本的例子?

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>定时器</title>
		<script type="text/javascript">
			window.onload = function(){
				var img = document.getElementById("img");
				var imgArr = ["img/01.jpg", "img/02.jpg", "img/03.jpg", "img/04.jpg", "img/05.jpg", "img/06.jpg"];
				var index = 0;
				var timer; 
				var btn1 = document.getElementById("btn1");
				btn1.onclick = function(){
					clearInterval(timer);
					timer = setInterval(function(){
						index ++;
						index = index % imgArr.length;
						img.src = imgArr[index];
					},1000);
				}
				var btn2 = document.getElementById("btn2");
				btn2.onclick = function(){
					clearInterval(timer);
				}
			}
		</script>
	</head>
	
	<body>
		<img src="img/01.jpg" id="img" style="width: 300px;"/><br />
		<button id="btn1">开始</button>
		<button id="btn2">停止</button>	
	</body>
</html>


好家伙,经过一下午的努力搜寻,终于看到了一个好例子如下:

renderRadar = () => {
clearInterval(radarTimer);
if (this.state.isPlayRadar) {
radarTimer = setInterval(() => {
this.setState({
radarImg: images[this.currentIndex],
craImg: this.currentIndex === 0 ? convection['iso'][0].imgUrl : convection['iso'][Math.ceil(this.currentIndex/10)-1].imgUrl
})
if (this.currentIndex < images.length-1) {
this.currentIndex += 1;
} else {
this.currentIndex = 0;
}
}, 200)
}
}

我来解释下为什么这个例子好,其实我并没有用到他里面的代码,只是看到了其中的 if (this.state.isPlayRadar) 这句代码给了我一个很大的启示,因为我前面说了,我需要将图片单张依次切换,但是我的图片又不能无限制的循环下去,所以需要设置一个判断当图片遍历完成后就停止。

2.3 代码

import React from 'react'
import { Layout, Divider } from 'antd'
import CustomBreadcrumb from '@/components/CustomBreadcrumb'
import '@/style/dlg.scss'
import img1 from '@/assets/images/1.jpg'
import img2 from '@/assets/images/2.jpg'
import img3 from '@/assets/images/3.jpg'
import img4 from '@/assets/images/4.jpg'
import img5 from '@/assets/images/5.jpg'


class DLGView extends React.Component {
    constructor(pros){
        super(pros);
        this.state = {
            imgs:[img1, img2, img3, img4,img5],   // 图片数组
            isPlayRadar: true, //是否需要播放
            timer: null,  // 定时器
            show: false,  // 前后按钮显示
            index: 0,//显示第几个图片
            tempSrc:img1,//默认初始为第一张图片
        }
    }

    start = () =>{
        let {timer, isPlayRadar} = this.state;
        clearInterval(timer);
        if(isPlayRadar){
            timer = setInterval(() => {
                this.state.index ++;
                this.state.index = this.state.index % this.state.imgs.length;

                this.setState({
                    tempSrc:this.state.imgs[this.state.index]
                });

                if (this.state.index >= this.state.imgs.length - 1 ) {
                    console.log('执行到了这里')
                    this.setState({
                        isPlayRadar: false,
                    })
                }
                //这句话不能少,否则无法停止掉
                clearInterval(timer);
            }, 2000);  //设定2000ms切换一张
        }


    }

    stop = () => { //重新加载一次
        let {timer} = this.state;
        clearInterval(timer);
        this.setState({
            isPlayRadar:true,
            index:0
        })
    }

    render() {
        return(
            <Layout>
                <div>
                    <CustomBreadcrumb arr={['数据安全', '攻击', '数据集重建攻击','DLG'] }></CustomBreadcrumb>
                </div>
                <div className="ReactCarousel">
                    <img src={this.state.tempSrc} id="img" style={{maxWidth:500, height:'auto'}}/>
                    <br />
                    <button id="btn2" onClick={this.stop}>再次演示</button>
                </div>
            </Layout>
        )
}

}

export default DLGView

2.4 补充

上面的代码基本就能实现我所需要的功能了,这里我之前碰到的一个问题就是,在React里面将src赋值到`里面,使用下面这种方式:
this.state.img.src = this.state.imgs[this.state.index];
就会出现下面错误

TypeError: Cannot set property 'src' of undefined

所以我才换成代码里面的这种写法:

this.setState({
     tempSrc:this.state.imgs[this.state.index]
});

其次就是自己写写代码时的一个小错误:
将this.stop 写成了this.stop(),然后出现了下面这个错误:

ReactJS: Maximum update depth exceeded error

解决办法就是将stop()改为this.stop

<button id="btn2" onClick={this.stop}>再次演示</button>

3. 参考文献

1. 用JS实现图片切换、定时器、轮播图

2. React使用定时器切换图片

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值