# React Hook Fetch Cancellation This folder follows a shared convention for network fetch cancellation in React hooks. ## Patterns ### 1. Hooks with manual refresh Hooks that expose a `refresh()` callback must use a long-lived `AbortController` stored in a ref: - `const abortRef = useRef(null); - Call `abortRef.current?.abort()` before starting a new request. - Create a fresh controller before every `refresh()` invocation. - Pass `controller.signal` to the API function. - In the cleanup effect, abort the controller when the hook unmounts. - After each `await`, check `signal.aborted` before updating state. This prevents stale responses from overwriting newer results and avoids React state updates after unmount. ### 2. One-shot mount-only requests Hooks that only fetch once inside `useEffect` and do not expose a manual refresh may use a local controller: - Create `const controller = new AbortController();` inside the effect. - Pass `controller.signal` to the request. - Abort it in the effect cleanup. - This is the simplest correct pattern for single-fetch hooks. ### 3. Do not use boolean cancelled flags for network requests A boolean `cancelled` flag is not sufficient because it does not stop the underlying fetch. Abort signals are the correct cancellation mechanism for fetch-based hooks. ## Polling with Drift Correction The `usePolledData` hook implements drift-corrected polling to maintain accurate polling intervals despite variable fetch durations. ### How it works - Uses self-scheduling timeouts instead of fixed `setInterval` - Tracks elapsed time from poll start to completion with `performance.now()` - Calculates next delay as `Math.max(0, pollInterval - elapsed)` - Schedules the next poll with drift compensation in the `onSuccess` callback - If a fetch takes longer than `pollInterval`, the next poll starts immediately (delay = 0) ### Why this matters With fixed `setInterval`: - If a fetch takes 2 seconds and `pollInterval` is 5 seconds - Actual polling interval becomes ~7 seconds (2s fetch + 5s interval) - Effective polling rate drifts and wastes bandwidth With drift correction: - Total time from poll start to next poll start is always ~5 seconds - Fetch duration doesn't affect the long-term polling rate - Bandwidth and CPU usage remain consistent