Combining Hooks – Advanced Patterns
Overview
These hooks are designed to compose. Here are common patterns for combining them.
Reduce polling on low battery
import { useBatteryAware, useNetworkAwarePolling } from "react-visibility-hooks";
function EfficientDashboard() { const { isLowBattery } = useBatteryAware();
const { data, isOnline, effectiveInterval } = useNetworkAwarePolling( () => fetch("/api/metrics").then((r) => r.json()), { // Back off when battery is low interval: isLowBattery ? 30_000 : 5_000, slowMultiplier: isLowBattery ? 5 : 3, }, );
return ( <div> <p>Online: {isOnline ? "yes" : "no"}</p> <p>Polling every {effectiveInterval / 1000}s</p> {isLowBattery && <p>⚠️ Low battery mode — reduced polling</p>} <pre>{JSON.stringify(data, null, 2)}</pre> </div> );}Session timeout with wake lock
Keep the screen on during the warning countdown so the user can see it:
import { useInactivityTimeout, useWakeLock } from "react-visibility-hooks";
function SessionGuard({ children }: { children: React.ReactNode }) { const { isWarning, isTimedOut, remainingSeconds, resetTimer } = useInactivityTimeout({ timeout: 300_000, warningBefore: 60_000, onTimeout: () => logout(), });
const { request, release } = useWakeLock();
useEffect(() => { if (isWarning) request(); else release(); }, [isWarning, request, release]);
if (isTimedOut) return <Redirect to="/login" />;
return ( <> {children} {isWarning && ( <Modal> <p>Session expires in {remainingSeconds}s</p> <button onClick={resetTimer}>Stay logged in</button> </Modal> )} </> );}Auto-pause video + analytics
Track watch time and pause video when the tab is hidden:
import { useAutoPauseVideo, usePageFocusEffect } from "react-visibility-hooks";
function TrackedVideo({ src }: { src: string }) { const videoRef = useRef<HTMLVideoElement>(null); const watchStart = useRef(Date.now());
useAutoPauseVideo(videoRef);
usePageFocusEffect({ onHidden: () => { const watchTime = Date.now() - watchStart.current; analytics.track("video_watch_time", { ms: watchTime }); }, onVisible: () => { watchStart.current = Date.now(); }, });
return <video ref={videoRef} src={src} controls />;}Idle + visibility for resource management
Tear down expensive resources when the user is both idle and on a hidden tab:
import { useIdleVisibility } from "react-visibility-hooks";
function LiveMap() { const { visible, idle } = useIdleVisibility(30_000); const shouldRender = visible || !idle;
return shouldRender ? <ExpensiveMapWidget /> : <MapPlaceholder />;}