React倒计时若干种实现方法
html:
<Button type="link" onClick={HandleSubmit} disabled={disableFlag}>{linkText}</Button>
const [disableFlag, setDisable] = useState<boolean>(false) const[linkText,setLinkText]=useState<string>('获取验证码')
1.原始版:
代码:
let num =10 let [num,setDisableSeconds]=useState<number>(10) const HandleSubmit = () => { setDisable(true); let x = setInterval(() => { if(num>0) { num=num-1; } setLinkText(num+''); if(num==0) { clearInterval(x); setDisable(false); setLinkText(linkText); } }, 1000); }
2.进阶版:
let newTimer =null; const [num, setDisableSeconds] = useState(10); const HandleSubmit = () => { setDisable(true); newTimer = setInterval(() => { if (num > 0) { setDisableSeconds((c) => c - 1); } }, 1000); } useEffect(()=>{ if(disableFlag){ setLinkText(num+''); if(num<0){ clearInterval(newTimer); setDisable(false); } } else { setLinkText('获取验证码'); } })
第二版初看效果可以,但经过分析发现不行,原因在于由于页面渲染,造成useEffect方法不停地被调用,造成死循环。
经过分析,并改进,有了第三版:
let [start, setStart] = useState<boolean>(false); useEffect(() => { let newTimer = null; if(start) { newTimer = setInterval(() => { if (num > 0) { setNumber((c) => c - 1); } }, 1000); if (disableFlag) { setLinkText(num + 'S后重试'); if (num <= 0) { setDisable(false); console.log('111111') } } else { setLinkText('获取验证码');
if(inputCode.length == 0) { setShowError1(true); } setStart(false); } return () => clearInterval(newTimer); } }, [num,disableFlag])
关键点在于,useEffect方法需要添加触发变量依赖:num及disableFlag,只有这2个变量发生变化时才能执行,经过验证发现效果ok。
浙公网安备 33010602011771号