취소 안 된 모든 fetch 는 미래의 race condition. AbortController 가 사용자가 마음 바꿀 때 in-flight 요청 취소하는 표준, 무료, 라이브러리 없는 방식.
Race condition
사용자가 검색 박스에 타이핑. 각 키스트로크가 fetch 발화. Fetch 들이 순서 어긋나서 반환 — 'r' 의 응답이 're' 의 응답 후 도착. 취소 없으면 더 옛 응답이 이김 (시간상 늦게 land 하니까), UI 가 잘못된 쿼리 결과 보여줌. 고침은 대체된 요청 abort.
API
Controller 생성, 그 signal 을 fetch 에 전달, 취소하려면 controller.abort() 호출. Fetch promise 가 AbortError 로 reject. 그 에러 타입을 에러 처리에서 필터 (예상된 것, 예외 아님).
통합 자리
- useEffect — 상단에 controller 생성, cleanup 함수 (effect 에서 반환) 에서 abort.
- 커스텀 hook — 같은 패턴, 그냥 hook 안.
- 이벤트 핸들러 — Controller 를 ref 에 저장해서 뒤따르는 핸들러 호출이 이전 거 abort 가능.
Timeout
Hard timeout 엔 AbortController 와 AbortSignal.timeout(ms) 결합: fetch(url, { signal: AbortSignal.timeout(5000) }) 가 5초 후 abort. 수동 + timeout 엔 AbortSignal.any([ctrl.signal, AbortSignal.timeout(5000)]) — 둘 중 하나 발화 시 abort.
모든 fetch 는 취소 방법 필요. '취소 필요 없어' 는 보통 '아직 race condition 안 만났어'. 한 번 규율 잡아 — hook 의 모든 fetch 가 signal 받고, 모든 cleanup 이 abort. 막는 버그가 QA 가 재현 못 하는 그 종류.