需求H5表单提交完毕实现5秒倒计时,网上很多案例,hooks却很少,如果你是vue用户抽出js就可以(这边我使用的ts)
思路:实现倒计时我们就要定时去轮询,那就是setInterval(),在使用定时器我们要在结束后清除定时器clearInterval(),释放内存
我们可以借助hooks 中useEffect的第二参数监听定时的变化,与第三参数return()=>类似销毁生命周期
代码
import {
Button,
Checkbox,
Dialog,
Mask,
Modal,
Radio,
Space,
TextArea,
} from 'antd-mobile';
import { useEffect, useState } from 'react';
const index = (props: any) => {
const [timeLeft, setTimeLeft] = useState<any>();
const [visible, setVisible] = useState(true);
const [language, setLanguage] = useState('ZH');
useEffect(() => {
setLanguage(localStorage.getItem('language') ?? 'ZH');
}, []);
// 倒计数
useEffect(() => {
console.log(timeLeft);
if (timeLeft === 0) {
setTimeLeft(null); // 初始化定时变量
setVisible(false); // 关闭自定义提示框
localStorage.clear(); // 清除localStorage
history.replace('/'); // 跳转登录页
}
if (!timeLeft) return;
const intervalId = setInterval(() => {
setTimeLeft(timeLeft - 1); //切记 hooks 不可以写--或++不支持
}, 1000);
return () => clearInterval(intervalId); // 清除定时器
}, [timeLeft]); // 此处类似vue的watch timeLeft变量变化就会触发
// 提交
const onSub = () => {
const params = {
projectResultId: localStorage.getItem('resultId'),
PhoneUniqueId: localStorage.getItem('PhoneUniqueId'),
answers: answers,
};
insertProjectResultAnswer(params).then((res) => { // 接口此处忽略
if (res.success) {
setTimeLeft(5); // 启动倒计时
setVisible(true); // 打开自定义弹框
} else {
Dialog.alert({
content: res.msg,
onConfirm: () => {},
});
}
});
return (
<>
<div
style={{
position: 'absolute',
bottom: '8px',
textAlign: 'center',
width: '100%',
}}
>
<Button className="btnNext" onClick={onSub}>
{language == 'ZH' ? '提交' : 'Submit'}
</Button>
</div>
<Mask visible={visible}>
<div className="overlayContent">
<div>
<img className="imgSuccess" />
</div>
<div>
{language == 'ZH'
? `您已全部完成,感谢您的参与。该界面将在${timeLeft}秒后自动关闭。`
: `Thank you for your participation. The interface will automatically close after ${timeLeft} seconds.`}
</div>
</div>
</Mask>
</>
);
export default index;
};
css 取自己需要的
// 遮盖层
.overlayContent {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
display: inline-block;
text-align: center;
width: 270px;
padding: 30px;
background: white;
border-radius: 16px;
}
.imgSuccess {
// display: block;
width: 142px;
height: 119px;
//此处图片替换成自己
background: url('../../../assets/images/success.png') no-repeat;
background-size: 100%;
border: 1px dashed gray;
margin-bottom: 20px;
}
.btnNext {
color: white;
font-size: 12px;
font-weight: bold;
background-color: #b18b34;
border: none;
width: 236px;
height: 39px;
border-radius: 18px;
}
请关注,点赞。