Pick any line to see why it is the way it is: the commit, the pull request and issue it came from, and what the agent was thinking.
| A click away from a live page arrives: pages stop refreshing themselves while a navigation is pending | 1 | import { useEffect } from "react"; |
| 2 | import { useNavigation, useRevalidator } from "react-router"; | |
| 3 | ||
| 4 | /** How often a page with something moving asks again. */ | |
| 5 | export const REFRESH_MS = 4000; | |
| 6 | ||
| 7 | /** | |
| 8 | * Revalidates the page every `everyMs` while `on` and the tab is visible. | |
| 9 | * Never while a navigation is pending: a revalidation then restarts the | |
| 10 | * navigation, aborting its loaders, so a click to a page slower than the | |
| 11 | * interval would never arrive. Never on top of a revalidation still going. | |
| 12 | */ | |
| 13 | export function useRefreshWhile(on: boolean, everyMs = REFRESH_MS) { | |
| 14 | const revalidator = useRevalidator(); | |
| 15 | const navigating = useNavigation().state !== "idle"; | |
| 16 | useEffect(() => { | |
| 17 | if (!on || navigating) return; | |
| 18 | const timer = setInterval(() => { | |
| 19 | if (document.visibilityState === "visible" && revalidator.state === "idle") revalidator.revalidate(); | |
| 20 | }, everyMs); | |
| 21 | return () => clearInterval(timer); | |
| 22 | }, [on, navigating, everyMs, revalidator]); | |
| 23 | } |