검색 입력창 자동완성 만들면서, 타이핑할 때마다 이전 요청을 취소하려고 AbortController를 붙였습니다. 컴포넌트 언마운트될 때도 취소하려고 cleanup에도 넣었고요.
useEffect(() => {
const ac = new AbortController()
fetch(url, { signal: ac.signal })
.then(r => r.json())
.then(setResults)
return () => ac.abort()
}, [url])동작 자체는 잘 됩니다. 근데 콘솔에 Uncaught (in promise) DOMException: The user aborted a request. 이게 계속 뜨네요. 특히 dev에서 컴포넌트가 처음 뜰 때부터 한 번 찍혀요. 기능은 되는데 에러가 남으니 찜찜합니다. 이거 놔둬도 되나요, 아니면 뭔가 잘못한 건가요?
댓글 4
해결은 catch를 붙이되, AbortError는 "의도한 취소"니까 조용히 무시하면 됩니다. catch에서 err.name이 'AbortError'면 그냥 return하고, 그 외의 진짜 네트워크 에러만 처리하세요. 이렇게 하면 콘솔이 깨끗해집니다.
dev에서 처음 뜰 때부터 한 번 찍히는 건 StrictMode의 이중 마운트 때문이에요. 마운트 → cleanup(여기서 abort) → 재마운트가 도니까, 첫 요청이 취소되면서 AbortError가 한 번 나는 거죠. 프로덕션에선 안 그러니 걱정 안 하셔도 됩니다. 오히려 이 로그가 cleanup이 제대로 걸려 있다는 증거예요.
한 가지 다른 점은 취소됐을 때 잡는 방법입니다. axios는 취소되면 CanceledError를 던지는데, axios.isCancel(err)로 판별하는 게 가장 안전해요. 그래서 catch에서 isCancel이면 무시, 아니면 실제 에러 처리 이렇게 가시면 됩니다. 패턴은 fetch 때랑 동일하고 판별 함수만 바뀐다고 보시면 돼요.