目录

1. 效果展示

React使用定时器自动切换图片_调用函数

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

2.4 补充

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

TypeError: Cannot set property 'src'

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

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使用定时器切换图片​