import React , { useState , useEffect , useRef } from 'react' ; import { Button } from 'antd' ; import { ButtonProps } from 'antd/es/button' ; import LocaleReceiver from 'antd/es/locale-provider/LocaleReceiver' ; import enUS from './locale/en_US' ; import { getTemplateText } from './utils' ; export interface SendCodeProps extends ButtonProps { start ? : boolean ; second ? : number ; initText ? : string ; runText ? : string ; resetText ? : string ; storageKey ? : string ; onEnd ? : ( ) => void ; } export interface SendCodeLocale { initText : string ; runText : string ; resetText : string ; } /**
 * 状态 0: 初始 1: 运行  2: 结束
 */ export type SendCodeStatus = 0 | 1 | 2 ; const SendCode = ( { start , initText , resetText , runText , onEnd , second , storageKey , ... rest } ) => { const [ status , setStatus ] = useState < SendCodeStatus > ( start ? 1 : 0 ) ; const [ runSecond , setRunSecond ] = useState < number | undefined > ( second ) ; const timer = useRef < NodeJS . Timer > ( null ) ; useEffect ( ( ) => { const storageLastSecond = ~ ~ ( ( + window . sessionStorage . getItem ( storageKey ) - new Date ( ) . getTime ( ) ) / 1000 ) ; if ( storageLastSecond > 0 && storageKey ) { startCountdown ( storageLastSecond ) ; } start && startCountdown ( ) ; return ( ) => { if ( timer . current ) { clearInterval ( timer . current ) ; } } ; } , [ start ] ) ; const startCountdown = ( value ? ) => { let second = value ? value : runSecond ; setStatus ( 1 ) ; setRunSecond ( second ) ; if ( storageKey ) { const runSecond = new Date ( ) . getTime ( ) + second * 1000 ; window . sessionStorage . setItem ( storageKey , runSecond + '' ) ; } timer . current = setInterval ( ( ) => { second -= 1 ; setRunSecond ( second ) ; if ( second <= 0 ) { timeout ( ) ; } } , 1000 ) ; } ; const timeout = ( ) => { setStatus ( 2 ) ; setRunSecond ( second ) ; if ( timer . current ) { clearInterval ( timer . current ) ; } if ( storageKey ) { window . sessionStorage . removeItem ( storageKey ) ; } onEnd ?. ( ) ; } ; const getText = ( sendCodeLocale ) => { switch ( status ) { case 1 : return getTemplateText ( runText || sendCodeLocale . runText , runSecond ) ; case 2 : return resetText || sendCodeLocale . resetText ; default : return initText || sendCodeLocale . initText ; } } ; const renderSendCode = ( sendCodeLocale ) => { return ( < Button { ... rest } disabled = { status === 1 } > { getText ( sendCodeLocale ) } < /Button>); } ; return ( < LocaleReceiver componentName = "SendCode" defaultLocale = { enUS } > { ( sendCodeLocale ) => renderSendCode ( sendCodeLocale ) } < /LocaleReceiver>); } ; SendCode . displayName = 'SendCode' ; SendCode . defaultProps = { start : false , second : 60 } ; export default SendCode ;