如何在 Nextjs 中创建间隔 API 调用?
How do I create an interval API call in Nextjs?
const LoadingPage = ({merchantId, order}) => {
const router = useRouter();
useEffect(() => {
if (order.status === "merchantAccepted") {
router.push(`/${merchantId}/success`);
}
}, []);
return (
<Column>
Waiting merchant to accept...
</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
}
};
};
我想做的是等待商家接受订单,这会更改数据库中的订单状态。然后我想获取将用于将用户重定向到另一个页面的状态。目前我正在使用 getServerSideProps 但此方法只获取一次,我需要刷新页面。如何在不刷新页面的情况下进行 API 调用?
谢谢。
这里有一些对您不利的事情,但很容易解决!
第一期在你的影响里。它只运行一次,而不是每次订单状态更改时运行。通过添加对 order.status
:
的依赖非常容易修复
useEffect(() => {
if (order.status === "merchantAccepted") {
router.push(`/${merchantId}/success`);
}
}, [order.status]);
现在,为了获得更新的订单信息,我们需要做一些更大的改变。您要做的第一件事是在状态中缓存 order
的值,这样您就可以允许组件调用 API 并更新状态。第二件事是传递一种更新订单状态的方法。结合对效果挂钩的更改以及这些要求,我为您想出了这个:
const LoadingPage = ({ getOrders, merchantId, order: orderProp }) => {
const router = useRouter();
const [order, setOrder] = useState(orderProp);
useEffect(() => {
if (order.status === "merchantAccepted") {
router.push(`/${merchantId}/success`);
}
}, [order.status]);
useEffect(() => {
// skip if merchant already accepted
if (order.status === "merchantAccepted") return;
// keep track of the timeout so we can cancel
let timeout;
// create an internal function to call the API to check for updates
const checkApi = async () => {
const updatedOrder = await getOrders("");
setOrder(updatedOrder);
if (updatedOrder.status !== "merchantAccepted") {
// wait 2 seconds to call again
timeout = setTimeout(checkApi, 2000);
}
}
// make the initial check in 2 seconds
timeout = setTimeout(checkApi, 2000);
// on unmount, make sure we cancel
return () => {
clearTimeout(timeout);
}
}, []); // only execute this effect on mount
return (
<Column>
Waiting merchant to accept...
</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,
getOrders
}
};
};
我想这会为您解决。如果您有任何问题,请告诉我!
const LoadingPage = ({merchantId, order}) => {
const router = useRouter();
useEffect(() => {
if (order.status === "merchantAccepted") {
router.push(`/${merchantId}/success`);
}
}, []);
return (
<Column>
Waiting merchant to accept...
</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
}
};
};
我想做的是等待商家接受订单,这会更改数据库中的订单状态。然后我想获取将用于将用户重定向到另一个页面的状态。目前我正在使用 getServerSideProps 但此方法只获取一次,我需要刷新页面。如何在不刷新页面的情况下进行 API 调用?
谢谢。
这里有一些对您不利的事情,但很容易解决!
第一期在你的影响里。它只运行一次,而不是每次订单状态更改时运行。通过添加对 order.status
:
useEffect(() => {
if (order.status === "merchantAccepted") {
router.push(`/${merchantId}/success`);
}
}, [order.status]);
现在,为了获得更新的订单信息,我们需要做一些更大的改变。您要做的第一件事是在状态中缓存 order
的值,这样您就可以允许组件调用 API 并更新状态。第二件事是传递一种更新订单状态的方法。结合对效果挂钩的更改以及这些要求,我为您想出了这个:
const LoadingPage = ({ getOrders, merchantId, order: orderProp }) => {
const router = useRouter();
const [order, setOrder] = useState(orderProp);
useEffect(() => {
if (order.status === "merchantAccepted") {
router.push(`/${merchantId}/success`);
}
}, [order.status]);
useEffect(() => {
// skip if merchant already accepted
if (order.status === "merchantAccepted") return;
// keep track of the timeout so we can cancel
let timeout;
// create an internal function to call the API to check for updates
const checkApi = async () => {
const updatedOrder = await getOrders("");
setOrder(updatedOrder);
if (updatedOrder.status !== "merchantAccepted") {
// wait 2 seconds to call again
timeout = setTimeout(checkApi, 2000);
}
}
// make the initial check in 2 seconds
timeout = setTimeout(checkApi, 2000);
// on unmount, make sure we cancel
return () => {
clearTimeout(timeout);
}
}, []); // only execute this effect on mount
return (
<Column>
Waiting merchant to accept...
</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,
getOrders
}
};
};
我想这会为您解决。如果您有任何问题,请告诉我!