reactjs - fetch with keepalive not firing in beforeunload event - Stack Overflow

I have a react app that is a helpcenter with articles. I am working on a feature to send information to

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条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信