如何在Next.js中实现间隔API调用,无刷新轮询订单状态
解决方案
核心思路是在前端实现定时轮询,定时从客户端发起API请求拉取最新订单状态,无需刷新页面即可感知状态变更。
具体修改步骤
- 1、新增客户端侧的订单查询接口调用方法,用来实时拉取最新订单数据
- 2、在
useEffect中创建定时器,按指定间隔(建议2-5秒,可根据业务需求调整)调用查询接口 - 3、检测到订单状态为
merchantAccepted时,清除定时器并执行跳转 - 4、页面卸载时额外清理定时器,避免内存泄漏
完整修改后的代码示例
import { useRouter } from 'next/router'; import { useEffect, useState } from 'react'; const LoadingPage = ({merchantId, order: initialOrder}) => { const router = useRouter(); // 存储最新订单状态 const [order, setOrder] = useState(initialOrder); useEffect(() => { // 首屏如果已经是接单状态,直接跳转 if (initialOrder.status === "merchantAccepted") { router.push(`/${merchantId}/success`); return; } // 客户端拉取最新订单的方法,替换为你实际的API请求逻辑 const fetchLatestOrder = async () => { try { const res = await fetch(`/api/orders?merchantId=${merchantId}`); const latestOrder = await res.json(); setOrder(latestOrder); // 检测状态 if (latestOrder.status === "merchantAccepted") { clearInterval(pollTimer); router.push(`/${merchantId}/success`); } // 可选:增加其他状态的处理逻辑,比如商户拒单跳转失败页 } catch (err) { console.error('拉取订单状态失败', err); } }; // 每3秒轮询一次 const pollTimer = setInterval(fetchLatestOrder, 3000); // 页面卸载时清理定时器 return () => clearInterval(pollTimer); }, [merchantId, router, initialOrder.status]); return ( <Column> 等待商户接单... </Column> ); }; export default LoadingPage; export const getServerSideProps = async (ctx) => { const {params} = ctx; const {merchantId} = params; const merchant = await getMerchant(merchantId); const order = await getOrders(""); return { props: { merchantId, merchant: merchant, order } }; };
可选优化方案
如果对实时性要求很高,轮询方案存在延迟的话,也可以替换为WebSocket长连接方案,商户更新订单状态后服务端主动推送给前端,无需客户端定时拉取,性能和实时性更好。
内容的提问来源于stack exchange,提问作者rockfox5
相关产品推荐
相关产品推荐

