最近在项目中使用计时器写一个倒计时按钮时,一开始没理清关系,后来终于找到了关键,做一个小demo备忘。
先把效果图贴上:
想做的效果如上,点击按钮后,按钮设为禁用,开始倒计时10s,倒计时结束即恢复。
思路如下:
1,将控制按钮状态、按钮文字和计时的秒数放在state中,用以改变状态。
2,写一个计时器方法,如setInterval(clock,1000);
,将clock方法每隔一秒执行一次,在clock方法中写更新状态的操作。
3,设一个变量值为计时的秒数,用以进行更新操作。这一步很关键,之前我就直接使用了state中的秒数来更新,但是发现state中的秒数在render()中是实时更新的,但它在一个方法中并不会更新,所以要赋值给一个变量来进行更新。
4,计时器方法执行到预期值时要关闭计时器方法,再将原状态更新回去。
把整体代码贴在下面:
import React, { PureComponent } from 'react';
import router from 'umi/router';
import { connect } from 'dva';
import {WingBlank, WhiteSpace,List, InputItem,Button,Toast} from 'antd-mobile';
import styles from './index.less';
const Item = List.Item;
class Demo extends PureComponent {
state = {
time: 10,
btnDisable:false,
btnContent: '发送验证码'
};
render() {
let timeChange;
let ti = this.state.time;
//关键在于用ti取代time进行计算和判断,因为time在render里不断刷新,但在方法中不会进行刷新
const clock =()=>{
if (ti > 0) {
//当ti>0时执行更新方法
ti = ti - 1;
this.setState({
time: ti,
btnContent: ti + "s之内不能再次发送验证码",
});
console.log(ti);
}else{
//当ti=0时执行终止循环方法
clearInterval(timeChange);
this.setState({
btnDisable: false,
time: 10,
btnContent: "发送验证码",
});
}
};
const sendCode = () =>{
this.setState({
btnDisable: true,
btnContent: "10s之内不能再次发送验证码",
});
//每隔一秒执行一次clock方法
timeChange = setInterval(clock,1000);
};
return (
<div>
<WhiteSpace size='xl' />
<WingBlank>
<WhiteSpace size='lg' style={
{backgroundColor: '#f5f5f9'}}/>
<Button type="primary" className={styles.send} inline onClick={sendCode} disabled={this.state.btnDisable}>{this.state.btnContent}</Button>
</WingBlank>
</div>
);
}
}
export default Demo;