I have a react app that is a helpcenter with articles. I am working on a feature to send information to the backend about how long an user has viewed an article.
For normal app flow (e.g. navigating away from an article to another page), I am using React Query and sending the request in the cleanup function for an useEffect. This works fine.
I am also trying to send the request upon page refresh or when closing the page. I am using fetch with keepalive: true
in an beforeunload
and also pagehide
events, so that the request is sent even though the page is closed. Here is an useEffect showing all this logic:
useEffect(() => {
lastActiveRef.current = new Date();
isTrackingRef.current = true;
const hasSentRef = { current: false };
const sendTime = (isUnload = false) => {
if (hasSentRef.current) return;
hasSentRef.current = true;
let finalTime = activeSecondsRef.current;
if (isTrackingRef.current) {
const currentSession = Math.floor(
(Date.now() - lastActiveRef.current.getTime()) / 1000
);
finalTime += currentSession;
}
if (finalTime > 1) {
console.log("Tracking time:", articleId, finalTime);
// console.log("sendBeacon", navigator.sendBeacon);
if (isUnload) {
// Use sendBeacon for unload events
console.log("Sending beacon:", finalTime);
fetch(
`${
import.meta.env.VITE_BACKEND_URL
}/public/add-view-duration/${articleId}?viewDuration=${finalTime}`,
{
method: "POST",
keepalive: true,
}
).catch((error) => console.error("Request failed:", error));
} else {
// Use normal mutation for component unmount
const id = parseInt(articleId ?? "");
sendTimeSpent({ articleId: id, seconds: finalTime });
}
}
};
const handleUnload = () => {
sendTime(true);
console.log("page has refreshed or closed");
};
window.addEventListener("beforeunload", handleUnload);
window.addEventListener("pagehide", handleUnload);
return () => {
sendTime(false); // Normal component unmount
window.removeEventListener("beforeunload", handleUnload);
window.removeEventListener("pagehide", handleUnload);
};
}, [articleId]);
The issue is that while handleUnload() is called correctly (tested with the console log) upon refresh, the request fails. Sometimes it works properly, but most of the time is showed as cancelled in the network tab.
I have also tried to use sendBeacon
instead, but it doesn't send any request at all. I have tried with adblocker turned off and in other browsers or in incognito mode.
Everything related to the backend is fine, since the react query mutation works with no issue
What might the issue be?
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745272708a4619846.html
评论列表(0条)