You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 08:45:04