首页 > 其他 > 详细

倒计时按钮封装实及表单处理

时间:2020-04-30 16:49:35      阅读:42      评论:0      收藏:0      [点我收藏+]

封装组件countDownButton.js

import React , {Component}from ‘react‘;
import { PropTypes} from ‘prop-types‘;
import {View,Text,TouchableOpacity,StyleSheet} from ‘react-native‘;

let isCalled = false, timeOut;//isCalled:falses表示可以调用目标方法  timeOut:存放定时器
export default class TimerButton extends Component {
    constructor(props) {
      super(props)
        this.state = {
            timerCount: this.props.timerCount || 60,//设置默认倒计时长 只要“||”前面为false,不管“||”后面是true还是false,都返回“||”后面的值。只要“||”前面为true,不管“||”后面是true还是false,都返回“||”前面的值。
            timerTitle: this.props.timerTitle || ‘获取验证码‘,//设置正常状态下按钮默认标题
            counting: false,//true为倒数时状态标志
        };
    }
    componentWillUnmount(){
        this.interval&&clearInterval(this.interval)
    }

    //倒计时方法
    _countDownAction(){
        const {timerCount}=this.state//获取timerCount最初值,触发倒计时后不更新此值,因为在timerCount时长内一直setInterval()方法
        this.interval = setInterval(() =>{
            const timer = this.state.timerCount - 1
            if(timer===0){
                this.interval&&clearInterval(this.interval);//清除倒计,恢复状态
                // console.log(‘timerCount‘,timerCount)
                this.setState({
                    timerCount: timerCount,//将最初获取的timerCount不变值更新回state
                    timerTitle: this.props.timerTitle || ‘获取验证码‘,
                    counting: false,
                })
                
            }else{
                this.setState({
                    timerCount:timer,
                    timerTitle: `重新获取(${timer}s)`,
                    counting: true,
                },
                ()=> console.log(‘timerCount2‘,this.state.timerCount)//更新state后立即实时获取的最新值的回调
                )
            }
        },1000)
    }

    //防止频繁点击方法
    callOnceInInterval = (functionTobeCalled, interval = 2000) => {
        // 当isCalled==false时
        if (isCalled==false) {//可以写成 if (!isCalled)
            // 将isCalled取反
            isCalled = true;
            // 清除定时器
            clearTimeout(timeOut);
            timeOut = setTimeout(() => {
                isCalled = false;//2秒后将全局变量isCalled变为false,为下次return functionTobeCalled()调用做准备,在此时间之内isCalled = true,故点击无效
            }, interval);
            return functionTobeCalled();//将目标方法返回出去实现有效点击
        }
    };
    

    render(){
        const {onClick,style,textStyle,} = this.props
        const {counting,timerTitle} = this.state
        return (
            <TouchableOpacity 
            activeOpacity={counting ? 1 : 0.7} //正常状态按下时不透明度为 0.7,倒数状态不透明度为1
            onPress={()=>{this.callOnceInInterval(onClick)}}
            disabled={counting?true:false}//判断倒数状态时呈禁用状态
            style={[counting?styles.btnStyle:style]}//倒数状态呈灰色  正常状态蓝色
            >
                <Text style={[styles.btnTextStyle,textStyle]}>{timerTitle}</Text>
            </TouchableOpacity>
        )
    }
}

const styles = StyleSheet.create({
    btnStyle:{
        // justifyContent:‘center‘,
        // alignItems:‘center‘,
        marginLeft:20,
        backgroundColor:‘#f0f0f0‘,
        borderRadius:6
    },
})

 

 

在页面中使用countDownButton组件:

WriteInfoScreen.js

/**
 *Created by *** on 2020/4/14
 */
import React, { Component, PureComponent } from ‘react‘;
import {
    StyleSheet,
    Text,
    Image,
    View,
    TextInput,
    ScrollView,
    FlatList,
    TouchableOpacity,
    Dimensions
} from ‘react-native‘;

import LoadingView from "../../../../component/Loading";
import * as api from "../../../../networking/Api";
import CountDownButton from ‘../child/countDownButton‘;

// 填写信息
const windowHeight = Dimensions.get(‘window‘).height;
var screenWidth = Dimensions.get(‘window‘).width;
export default class WriteInfoScreen extends Component {
    constructor() {
        super(...arguments)
        this.state = {
            accountName:‘‘,//用户名
            idCard:‘‘,//身份证号
            phoneNumber:‘‘,//预留手机号
            bankAccount:‘‘,//银行账户

            // accountName:‘梦玲珑‘,//用户名
            // idCard:‘440106199003078716‘,//身份证号
            // phoneNumber:‘13600000013‘,//预留手机号
            // bankAccount:‘6217900000000000006‘,//银行账户
            verificationCode:‘‘,//验证码
            banckItem:{},//银行卡选择列表信息
            ChannelItem:{},//支付渠道选择列表信息
            customerId:‘‘,
            nameAndIdCard:‘‘,
            data:‘‘,//授权结果
            message:‘‘,//授权结果说明
            getCodeData:‘‘,//获取验证码返回数据(getCodeData.id或者getCodeData.reqSn)
            code:null,//用于授权结果页判断跳转
            enable:false//用于限制倒数按钮状态
        }
    }

    componentDidMount(){
        const { banckItem, //银行卡选择列表信息
                ChannelItem, //支付渠道选择列表信息
                customerId,//用户ID
                nameAndIdCard,
                phoneNumber
            } = this.props.navigation.state.params.data
        const {customer_name,person_identity_card}=nameAndIdCard
        this.setState({
            banckItem: banckItem,
            ChannelItem:ChannelItem,
            customerId:customerId,
            accountName:customer_name,
            phoneNumber:phoneNumber,
            // idCard:person_identity_card,
        })
        
        console.log(‘banckItem:‘,banckItem,‘ChannelItem:‘,ChannelItem,‘customerId:‘,customerId,‘nameAndIdCard:‘,nameAndIdCard)
    }

    //授权结果页返回重制输入框值
    componentWillReceiveProps(nextProps){
        if(nextProps.navigation.state.params.inputVlue){
            const{accountName,idCard,phoneNumber,bankAccount} = nextProps.navigation.state.params.inputVlue
            console.log(‘授权结果页返回重制输入框值‘) 
            this.setState({
                accountName:accountName,
                phoneNumber: phoneNumber,
                idCard: idCard,
                bankAccount: bankAccount,
                verificationCode:‘‘,
            })
        }
    }

    //立即开通
    _openNow = ()=>{
        const{bankAccount,phoneNumber,idCard,accountName,verificationCode,customerId,getCodeData}=this.state;
            const{
                bank,//银行卡代码
                bankName,//银行名称
            }=this.state.banckItem;
            const{
                loanType,//借款类型
                loanTypeAuth,//还款渠道
                payType,//支付方式
            }=this.state.ChannelItem;

            // 输入框值打印
            console.log(‘accountName:‘,accountName,‘idCard:‘,idCard,‘phoneNumber:‘,phoneNumber,‘bankAccount:‘,bankAccount,‘verificationCode:‘,verificationCode,);

            // 判断各项是否为空
            if(accountName==‘‘){
                EDMoney.Toast.show(‘请输入户名‘)
            }else if(idCard==‘‘){
                EDMoney.Toast.show(‘请输入身份证号‘) 
            }else if(phoneNumber==‘‘){
                EDMoney.Toast.show(‘请输入预留手机号‘)
            }else if(bankAccount==‘‘){
                EDMoney.Toast.show(‘请输入银行账户‘)
            }else if(verificationCode==‘‘){
                EDMoney.Toast.show(‘请输入验证码‘)
            }else{
                //当reqSn且id都是Undefined的时候(未获取验证码状态)
                if(!getCodeData.reqSn && !getCodeData.id){
                    EDMoney.Toast.show(‘请先获取验证码‘)
                }else{
                    //当存在reqSn时,通联渠道已获取验证码
                    if(getCodeData.reqSn){
                        console.log(‘reqSn+++:‘,getCodeData.reqSn)
                        // console.log(‘id+++:‘,getCodeData.id)
                        //通联系列渠道
                        api.confirmDingCardreqSn(customerId,bankAccount,bank,phoneNumber,idCard,loanType,loanTypeAuth,accountName,payType,bankName,verificationCode,getCodeData.reqSn)
                        .then((res) => {
                            console.log(‘confirmDingCardreqSn  res+++++:‘,res)
                            //请求成功后刷新数据
                            this.setState({
                                data: res.data,//交易成功或失败
                                message: res.message,//作成功或操作失败
                                code: res.code,
                                getCodeData:‘‘//作废上一轮已使用过的验证码(重置后需重新获取才能进行下一轮立即开通请求)
                            })
                            this.props.navigation.navigate(‘authorizeResult‘,{ data:this.state.data,message:this.state.message,code:this.state.code,inputVlue:this.state,})
                        })
                        .catch((error) => {
                            console.log(‘confirmDingCardreqSn  error+++++:‘,error)
                            //success:false时不符合后台接口条件,弹窗提示
                            if (error.errors) {
                                console.log(‘confirmDingCardreqSn  error.errors+++++:‘,error.errors)
                                EDMoney.Toast.show(error.errors._error)
                                // this.props.navigation.navigate(‘authorizeResult‘,{ data:this.state.data,message:this.state.message})
                            } else {
                                // 网络错误,请求失败(未连接后台)
                                EDMoney.Toast.show(‘网络错误‘)
                            }
                        })
                        
                    }else{
                        //当其他情况时,其他渠道已获取验证码
                        // console.log(‘reqSn---:‘,getCodeData.reqSn)
                        console.log(‘id---:‘,getCodeData.id)
                        //其他渠道
                        api.confirmDingCardID(customerId,bankAccount,bank,phoneNumber,idCard,loanType,loanTypeAuth,accountName,payType,bankName,verificationCode,getCodeData.id+‘‘)
                        .then((res) => {
                            console.log(‘confirmDingCardID res+++++:‘,res)
                            //请求成功后刷新数据
                            this.setState({
                                data: res.data,//交易成功或失败
                                message: res.message,//作成功或操作失败
                                code: res.code,
                                getCodeData:‘‘//作废上一轮已使用过的验证码(重置后需重新获取才能进行下一轮立即开通请求)
                            })
                            this.props.navigation.navigate(‘authorizeResult‘,{ data:this.state.data,message:this.state.message,code:this.state.code,inputVlue:this.state,})
                        })
                        .catch((error) => {
                            console.log(‘请求失败+++++:‘,error)
                            if (error.errors) {
                                // EDMoney.Toast.show(error.errors._error)
                                // this.props.navigation.navigate(‘authorizeResult‘,{ data:this.state.data,message:this.state.message})
                            } else {
                                EDMoney.Toast.show(‘网络错误‘)
                            }
                        })
                        
                    }
                }
            }   
    }

    // 输入框失去焦点后执行
    updateText = (text,sign)=>{
        console.log(‘text‘,text)
        // 更新不同输入框的值到State
        switch (sign) {
            case ‘accountName‘:
                    this.setState({accountName : text})
                    break;     
            case ‘idCard‘:
                var idCardReg = /^[0-9]{18}/;//18位数字规则
                //不符合规则执行
                if(!idCardReg.test(text)){
                    if(text){
                        EDMoney.Toast.show(‘身份证号格式不正确!‘)
                         this.setState({idCard : text})
                        //当输入值不符合格式时,先更新value值为‘ ’(最初是为‘’)
                        //  this.setState({idCard : ‘ ‘})
                        // 然后瞬间再次恢复value值回最初始的‘’,起到重置输入框效果
                        // setTimeout(() =>{
                        //     this.setState({idCard : ‘‘})
                        // }, 10)
                        break
                    }else{
                        this.setState({idCard : ‘‘})
                        break
                    }
                }else{
                    this.setState({idCard : text})
                    break;
                }
            case ‘phoneNumber‘:
                var phoneNumberReg = /^1[3-9]\d{9}$/;//11位手机号码规则
                if(!phoneNumberReg.test(text)){
                    if(text){
                        EDMoney.Toast.show(‘手机号码格式不正确!‘)
                        this.setState({phoneNumber : text})
                        // this.setState({phoneNumber : ‘ ‘})
                        // setTimeout(() =>{
                        //     this.setState({phoneNumber : ‘‘})
                        // }, 10)
                        break
                    }else{
                        this.setState({phoneNumber : ‘‘})
                        break
                    }
                }else{
                    this.setState({phoneNumber : text})
                    break;
                }
            case ‘bankAccount‘:
                var bankAccountReg = /^[0-9]*$/;//纯数字银行卡规则
                if(!bankAccountReg.test(text)){
                    if(text){
                        EDMoney.Toast.show(‘银行卡号格式不对!‘)
                        this.setState({phoneNumber : text})
                        // this.setState({bankAccount : ‘ ‘})
                        // setTimeout(() =>{
                        //     this.setState({bankAccount : ‘‘})
                        // }, 10)
                        break
                    }else{
                        this.setState({phoneNumber : ‘‘})
                        break
                    }
                }else{
                    this.setState({bankAccount : text})
                    break;
                }
            case ‘verificationCode‘:
                var verificationCodeReg = /^\d{6}$/;//6位验证码规则
                if(!verificationCodeReg.test(text)){
                    // 有值且不符合条件
                    if(text){
                        EDMoney.Toast.show(‘请输入6位数的验证码!‘)
                        this.setState({verificationCode : text})
                        // this.setState({verificationCode : ‘ ‘})
                        // setTimeout(() =>{
                        //     this.setState({verificationCode : ‘‘})
                        // }, 10)   
                        break
                    }else{
                        // 空且不符合条件
                        this.setState({verificationCode : ‘‘})
                        break
                    }
                }else{
                    // 有值且符合条件
                    this.setState({verificationCode : text})
                    break;
                }
            default:
                break;
        }
    }

    // 获取验证码方法
    _getCode = ()=>{
            const{bankAccount,phoneNumber,idCard,accountName,customerId,}=this.state;
            console.log(‘accountName:‘,accountName,‘idCard:‘,idCard,‘phoneNumber:‘,phoneNumber,‘bankAccount:‘,bankAccount,);
            
            const{
                bank,//银行卡代码
                bankName,//银行名称
            }=this.state.banckItem;
            const{
                loanType,//借款类型
                loanTypeAuth,//还款渠道
                payType,//支付方式
            }=this.state.ChannelItem;

            //判断信息是否填写完整
            if(accountName==‘‘){
                EDMoney.Toast.show(‘请输入户名‘)
                return false;//如果为空跳出_getCode方法以阻止请求
            }else if(idCard==‘‘){
                EDMoney.Toast.show(‘请输入身份证号‘)
                return false;
            }else if(phoneNumber==‘‘){
                EDMoney.Toast.show(‘请输入预留手机号‘)
                return false;
            }else if(bankAccount==‘‘){
                EDMoney.Toast.show(‘请输入银行账户‘)
                return false;
            }else{
                console.log(‘customerId:‘,customerId,‘bankAccount:‘,bankAccount,‘bank:‘,bank,‘phoneNumber:‘,phoneNumber,‘idCard:‘,idCard,‘loanType:‘,loanType,‘loanTypeAuth:‘,loanTypeAuth,‘accountName:‘,
                accountName,‘payType:‘,payType,‘bankName:‘,bankName,);
                
                this.refs.countDown._countDownAction();//请求前调用倒计时组件的方法开始倒计时
                api.binDingCard(customerId,bankAccount,bank,phoneNumber,idCard,loanType,loanTypeAuth,accountName,payType,bankName,)
                .then((res) => {
                    console.log(‘res.data‘,res.data)
                    // 请求成功后刷新数据
                    this.setState({
                        getCodeData: res.data,
                    })
                    console.log(‘获取验证码成功开始倒计‘)
                    // this.refs.countDown._countDownAction();//请求成功并后台验证通过后调用倒计时组件的方法开始倒计时
                    
                })
                .catch((error) => {
                    if (error.errors) {
                        EDMoney.Toast.show(error.errors._error)
                    } else {
                        EDMoney.Toast.show(‘网络错误‘)
                    }
                })
            }
        
    }

    render() {
        const { banckItem, ChannelItem } = this.props.navigation.state.params.data
        const{bankAccount,phoneNumber,idCard,accountName,verificationCode,enable}=this.state;
        return (
            <View style={styles.root}>
                <ScrollView showsVerticalScrollIndicator={false} keyboardShouldPersistTaps={‘never‘}>
                    <View>
                        <View style={styles.channelName}>
                            <Text style={styles.channelNameText}>{ChannelItem.channelPayName}</Text>
                        </View>
                        <View style={styles.write} >
                            <View style={styles.infoItem}>
                                <Text style={styles.infoItemText}>户名</Text>
                                <TextInput
                                        underlineColorAndroid=‘transparent‘//去除安卓端下划线
                                        placeholder=‘请输入户名‘
                                        // placeholderTextColor="#e1e1e1"
                                        onBlur={(event) => this.updateText(
                                            event.nativeEvent.text,‘accountName‘
                                        )}
                                        value={accountName}
                                        style={styles.inputStyle}
                                    ></TextInput>
                            </View>
                            <View style={styles.infoItem}>
                                <Text style={styles.infoItemText}>身份证号</Text>
                                <TextInput
                                        underlineColorAndroid=‘transparent‘
                                        placeholder=‘请输入身份证号‘
                                        // placeholderTextColor="#e1e1e1"
                                        onBlur={(event) => this.updateText(
                                            event.nativeEvent.text,‘idCard‘
                                        )}
                                        keyboardType=‘numeric‘
                                        value={idCard}
                                        style={styles.inputStyle}
                                        maxLength={18}
                                    ></TextInput>
                            </View>
                            <View style={[styles.infoItem,{marginBottom:0}]}>
                                <Text style={styles.infoItemText}>预留手机号</Text>
                                <TextInput
                                        underlineColorAndroid=‘transparent‘
                                        placeholder=‘请输入预留手机号‘
                                        // placeholderTextColor="#e1e1e1"
                                        onBlur={(event) => this.updateText(
                                            event.nativeEvent.text,‘phoneNumber‘
                                        )}
                                        keyboardType=‘numeric‘
                                        value={phoneNumber}
                                        style={styles.inputStyle}
                                        maxLength={11}
                                    ></TextInput>
                            </View>
                            <View style={[styles.infoItem,{marginBottom:0}]}>
                                <Text style={styles.infoItemText}></Text>
                                <Text style={[styles.inputStyle,{textAlign:‘center‘,borderWidth:0,lineHeight:50,backgroundColor:0}]}>{banckItem.bankName}</Text>
                            </View>
                            <View style={styles.infoItem}>
                                <Text style={styles.infoItemText}>银行账户</Text>
                                <TextInput
                                        underlineColorAndroid=‘transparent‘
                                        placeholder=‘请输入银行账号‘
                                        // placeholderTextColor="#e1e1e1"
                                        onBlur={(event) => this.updateText(
                                            event.nativeEvent.text,‘bankAccount‘
                                        )}
                                        keyboardType=‘numeric‘
                                        value={bankAccount}
                                        style={styles.inputStyle}
                                    ></TextInput>
                            </View>
                            <View style={styles.infoItem}>
                                <TextInput
                                        underlineColorAndroid=‘transparent‘
                                        placeholder=‘请输入验证码‘
                                        // placeholderTextColor="#e1e1e1"
                                        onBlur={(event) => this.updateText(
                                            event.nativeEvent.text,‘verificationCode‘
                                        )}
                                        keyboardType=‘numeric‘
                                        maxLength={6}
                                        value={verificationCode}
                                        style={styles.code}
                                    ></TextInput>
                                < CountDownButton
                                style={{marginLeft:20,backgroundColor:‘#00a8ff‘,borderRadius:6}}
                                textStyle={{width: 120,color: ‘#fff‘,fontSize: 17,lineHeight:50,textAlign:‘center‘}}
                                timerCount={10}//设置倒计时长
                                timerTitle={‘获取验证码‘}//设置按钮默认标题
                                onClick={this._getCode}
                                ref="countDown"
                                // timerActiveTitle={[‘请在(‘,‘s)后重试‘]}//倒计时的数字会插在数组第一项之后,如:[‘请在‘, ‘秒后重新获取‘],显示为【请在60秒后重新获取】
                                />
                            </View>
                        </View>
                                         
                    </View>
                    
                </ScrollView>
                <View>
                    <TouchableOpacity
                        onPress={()=>this._openNow()}
                        style={{backgroundColor:‘#00a8ff‘}}>
                        <Text style={styles.getCode}>立即开通</Text>
                    </TouchableOpacity>
                </View>  
            </View>
        )
    }

}



const styles = StyleSheet.create({
    root:{
        backgroundColor:‘#f0f0f0‘,
        flex:1
    },
    channelName:{
        backgroundColor:‘#fff‘,
        borderTopColor:‘#e6e6e6‘,
        borderTopWidth:1,
        padding:10,
        marginBottom:10,
        minWidth:300
        
    },
    channelNameText:{
        fontSize:20,
        lineHeight:45,
        textAlign:‘center‘
    },
    infoItem:{
        flexDirection:‘row‘,
        alignItems: ‘center‘,
        marginBottom:20
    },
    infoItemText:{
        fontSize:18,
        flex:2,
        lineHeight:50,
        textAlign:‘left‘, 
    },
    write:{
        minWidth:300,
        backgroundColor:‘#fff‘,
        paddingLeft:15,
        paddingRight:15,
        paddingTop:20
    },
    inputStyle:{
        height:50,
        fontSize:18,
        textAlign:‘left‘, 
        paddingLeft:10,
        flex:4,
        borderRadius:4,
        backgroundColor:‘#f0f0f0‘
    },
    code:{
        height:50,
        fontSize:18,
        textAlign:‘left‘, 
        paddingLeft:10,
        flex:4,
        borderRadius:3,
        backgroundColor:‘#f0f0f0‘
    },
    getCode:{
        fontSize:18,
        color:‘#fff‘,
        lineHeight:60,
        textAlign:‘center‘, 
        marginLeft:10
    }
})

 

倒计时按钮封装实及表单处理

原文:https://www.cnblogs.com/itgezhu/p/12809681.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!