技术

手机验证码倒计时功能

验证码相关

手机验证码倒计时功能

实现思路:简单定时器+逻辑判断 手机号的合法性可以在前端直接使用正则进行判断 一分钟内是否重复请求验证码的操作应该由后端来判断,前端页面的刷新、路由可能会影响定时器的显示 例如请求了一次验证码,关闭网页或程序,一分钟内再次进入登录页,请求验证码。这种情况前端判断比较麻烦,直接由后端处理比较好 记得清除上一个定时器,避免内存问题

简易代码:

const [count, setCount] = useState(60);
const [timer, setTimer] = useState<NodeJS.Timeout | null>(null);
const [isCounting , setIsCounting] = useState(false);
    const getCode = () => {
        if(isCounting){
            return
        }
        if (phoneNo === '' || !(/^1[3456789]\d{9}$/.test(phoneNo))) {
            Taro.showToast({
                title: '手机号格式错误',
                duration: 2000,
                icon: 'none',
            })
        } else {
            setIsCounting(true);
            apiwx.userSendCode({ mobile: phoneNo }).then((res) => {
                if (res.code == 0) {
                    console.log('验证码发送成功');
                    Taro.showToast({
                        title:'验证码发送成功',
                        icon:'none',
                        duration:2000,
                    })
                    setShowBtn(false);
                    setCodeTs(count + 'S重发');
                    const Timer = setInterval(() => {
                        setCount(prevCount => {
                            if (prevCount <= 1) {
                                clearInterval(Timer);
                                setShowBtn(true);
                                setCount(60);
                                setCodeTs('获取验证码');
                                setIsCounting(false);
                                return 60;
                            }
                            setCodeTs((prevCount - 1) + 'S重发');
                            return prevCount - 1;
                        });
                    }, 1000);
                    setTimer(Timer);
                } else if(res.code === 'xxxx'){
                    setIsCounting(false);
                    setShowBtn(true);
                    Taro.showToast({
                        title:'一分钟内请勿重复发送验证码',
                        duration:2000,
                        icon:'none',
                    })
                }
                else {
                    setIsCounting(false);
                    setShowBtn(true);
                    Taro.showToast({
                        title: res.message,
                        icon: 'none',
                        duration: 2000,
                    })
                }
            });
        }
    };

时间戳应该存在全局状态中,避免重复请求验证码时,时间戳被重置

全局状态也不能保证页面关闭后时间戳不会被重置,业务有需求的话最好从后端拿时间戳,然后进行倒计时