React Native实现验证码倒计时功能

来源:互联网 发布:linux 启动命令模式 编辑:程序博客网 时间:2024/05/17 23:04

React Native实现验证码倒计时功能

实现倒计时功能使用的是核心方法 setInterval,setInterval() 方法会不停地调用函数,直到 clearInterval() 被调用或窗口被关闭。

startCountDown() {    this.interval = setInterval(() => {       this.setState({           countdown: this.getCountdown() - 1       });    },1000);}

当 App 切换至后台之后,setInterval 将不会执行,而当 App 从后台切换至前台时,setInterval 将继续执行,所以对于切换至后台的情况需要监听 App 状态,记录变化的时间。React Native 提供了 AppState 监听 App 状态改变,AppState 一共有三种状态,包括以下三种。

  • active - 应用正在前台运行
  • background - 应用正在后台运行。用户既可能在别的应用中,也可能在桌面
  • inactive - 这是一个过渡状态,不会在正常的 React Native 应用中出现
componentDidMount() {    AppState.addEventListener('change', this._handleAppStateChange);}componentWillUnmount() {    AppState.removeEventListener('change', this._handleAppStateChange);    this.interval && clearInterval(this.interval);  } _handleAppStateChange = (nextAppState) => {    if (this.state.appState === 'active' && nextAppState.match(/inactive|background/)) {          this.backgroundTime = new Date().getTime() / 1000;    }    if (this.state.appState.match(/inactive|background/) && nextAppState === 'active') {          this.backgroundTime = utils.fomatFloat(new Date().getTime() / 1000 - this.backgroundTime,0);     }     this.setState({appState: nextAppState}); }

最后完整实现代码

import React, {    PureComponent,} from 'react';import {    TouchableOpacity,    Text,    AppState,    StyleSheet} from 'react-native';function fomatFloat(src, pos) {    return Math.round(src * Math.pow(10, pos)) / Math.pow(10, pos);}class CountDown extends PureComponent {    constructor(props) {        super(props);        this.state = {            appState: AppState.currentState,            countdown: -1,            disabled: false        };        this.backgroundTime = 0;    }    componentDidMount() {        AppState.addEventListener('change', this._handleAppStateChange);    }    componentWillUnmount() {        AppState.removeEventListener('change', this._handleAppStateChange);        this.interval && clearInterval(this.interval);    }    _handleAppStateChange = (nextAppState) => {        if (this.state.appState === 'active' && nextAppState.match(/inactive|background/)) {            this.backgroundTime = new Date().getTime() / 1000;        }        if (this.state.appState.match(/inactive|background/) && nextAppState === 'active') {            this.backgroundTime = fomatFloat(new Date().getTime() / 1000 - this.backgroundTime,0);        }        this.setState({appState: nextAppState});    }    setCountdown(countdown) {        this.setState({           countdown: countdown        });    }    getCountdown() {        return this.state.countdown;    }    startCountDown() {        this.interval = setInterval(() => {            if (this.backgroundTime < this.getCountdown()) {                this.setState({                    countdown: this.getCountdown() - this.backgroundTime - 1                },()=>{                    this.backgroundTime = 0;                    if (this.getCountdown() < 0) {                        this.interval && clearInterval(this.interval);                    }                    if (this.getCountdown() >= 0) {                        this.setButtonClickDisable(true);                    } else {                        this.setButtonClickDisable(false);                    }                });            } else {                this.setCountdown(-1);                this.setButtonClickDisable(false);                this.interval && clearInterval(this.interval);            }        }, 1000);        this.setButtonClickDisable(true);    }    setButtonClickDisable(enable) {        this.setState({           disabled: enable        });    }    onPress = () => {        this.setCountdown(120);        this.startCountDown();    }    render() {        return (            <TouchableOpacity disabled={this.state.disabled} onPress={this.onPress} style={styles.vcode}>                {this.state.countdown >= 0 ?                    <Text style={styles.vcodeText}>                        {`${this.state.countdown}`}秒                    </Text> :                    <Text style={styles.vcodeText}>                        获取验证码                    </Text>                }            </TouchableOpacity>        );    }}const styles = StyleSheet.create({    vcode: {        borderRadius: 5,        borderColor: '#ccc',        borderWidth: 1,        height:40,        justifyContent: 'center',        backgroundColor:'white',        alignItems: 'center',        marginLeft: 5    },    vcodeText: {        color: 'rgba(255,165,0,1.0)',    }});export default CountDown;
原创粉丝点击