Bin
2025-12-17 2b99d77d73ba568beff0a549534017caaad8a6de
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import { useCallback, useEffect, useMemo, useRef } from "react";
 
export interface AbortControllerHook {
  controller: React.MutableRefObject<AbortController>;
  renew: () => void;
  abort: () => void;
}
 
/**
 * Creates a shared AbortController, which can be used to abort requests.
 * Automatically cancels the current controller when the component unmounts.
 */
export const useAbortController = () => {
  const controller = useRef(new AbortController());
 
  const abort = useCallback(() => {
    const ctrl = controller.current;
    if (ctrl.signal.aborted) return;
 
    ctrl.abort();
  }, []);
 
  useEffect(() => {
    return () => {
      abort();
    };
  }, [abort]);
 
  const renew = useCallback(() => {
    abort();
    controller.current = new AbortController();
  }, [abort]);
 
  const abortController: AbortControllerHook = useMemo(
    () => ({
      controller,
      renew,
      abort,
    }),
    [controller, renew, abort],
  );
 
  return abortController;
};