ReactJS如何根据货件时效数据实现定时器到期触发后端API调用
实现步骤
1. 时间差值计算预处理
你当前给出的shipmentCreationTime和shipmentExpiryTime只有12小时制的时分数据,默认按当天同一日期处理,先把时间转成时间戳计算倒计时总时长:
// 12小时制时间转当天时间戳 const parseTimeToTimestamp = (timeStr) => { const [time, modifier] = timeStr.split(' '); let [hours, minutes] = time.split(':'); hours = parseInt(hours, 10); if (modifier === 'PM' && hours !== 12) hours += 12; if (modifier === 'AM' && hours === 12) hours = 0; const date = new Date(); date.setHours(hours, minutes, 0, 0); return date.getTime(); } // 计算剩余倒计时毫秒数 const getCountdownTime = (shipmentData) => { const expiryTs = parseTimeToTimestamp(shipmentData.shipmentExpiryTime); const nowTs = Date.now(); return expiryTs > nowTs ? expiryTs - nowTs : 0; }
如果你的实际业务中货件时间带完整日期,直接把完整日期字符串传入new Date()转时间戳即可,不需要上述转换逻辑。
2. React组件内倒计时实现
用函数组件+Hooks实现,注意组件卸载时清理定时器,避免内存泄漏和无效接口调用:
import { useState, useEffect } from 'react'; import axios from 'axios'; // 也可以用原生fetch替代 const ShipmentCountdown = ({ shipmentData }) => { const [remainingTime, setRemainingTime] = useState(() => getCountdownTime(shipmentData)); const shipmentId = shipmentData._id; // 倒计时核心逻辑 useEffect(() => { // 打开页面时已过过期时间,直接触发过期逻辑 if (remainingTime <= 0) { handleExpireShipment(shipmentId); return; } const timer = setInterval(() => { setRemainingTime(prev => { if (prev <= 1000) { clearInterval(timer); return 0; } return prev - 1000; }); }, 1000); // 依赖变更/组件卸载时清理定时器 return () => clearInterval(timer); }, [remainingTime, shipmentId]); // 调用后端过期接口 const handleExpireShipment = async (offerId) => { try { const res = await axios.post('替换为你的后端实际接口地址/expireShipmentOffer', { shipmentOfferId: offerId }); if (res.data.status === 200) { console.log('货件已标记过期', res.data.message); // 此处可补充业务逻辑:刷新列表、弹出提示等 } } catch (err) { console.error('调用过期接口失败', err.message); } } // 剩余时间格式化展示 const formatTime = (ms) => { const totalSeconds = Math.floor(ms / 1000); const minutes = Math.floor(totalSeconds / 60); const seconds = totalSeconds % 60; return `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`; } return ( <div className="countdown"> {remainingTime > 0 ? ( <p>货件剩余有效期:{formatTime(remainingTime)}</p> ) : ( <p>该货件已过期</p> )} </div> ) } export default ShipmentCountdown;
3. 注意事项
- 前端倒计时仅为展示层辅助逻辑,后端必须做时间校验,避免用户修改本地时间绕过过期规则,可在
expireShipmentOffer接口中先判断当前真实时间是否超过货件过期时间,再执行更新操作 - 多货件场景下每个货件对应单独的定时器即可,不会互相干扰
内容的提问来源于stack exchange,提问作者Haseeb Ahmed
相关产品推荐
相关产品推荐

