오늘 나는 커스텀 훅을 진정으로 이해했다 (그리고 직접 만들어봤다)
Source: Dev.to
Overview
오늘은 달랐습니다. 새로운 React 기능을 배운 것이 아니라, 코드 구조에 대한 사고 방식을 한 단계 끌어올렸기 때문이죠. 저는 단순히 컴포넌트를 작성한 것이 아니라, 직접 커스텀 훅을 만들기 시작했고, 그 순간 모든 것이 바뀌었습니다.
프로젝트를 진행하면서 다음과 같은 패턴을 발견했습니다:
- 한 컴포넌트에 키보드 로직
- 다른 컴포넌트에 LocalStorage 로직
- 또 다른 곳에 영화‑조회 로직
useEffect가 여기저기서 많이 사용되고, 동일한 패턴이 반복되며, 모든 것이 UI에 강하게 결합돼 있었습니다. 그때 깨달았습니다. 이 로직은 UI에 속하지 않고 별도의 추상화에 들어가야 한다는 것을. 바로 그때 커스텀 훅을 진정으로 이해하게 되었습니다.
커스텀 훅은 동작을 UI와 분리하는 방법입니다. 이를 통해 다음을 할 수 있습니다:
- 로직 재사용
- 부수 효과 격리
- 컴포넌트 단순화
- 파일이 아니라 기능 단위로 사고
useKey — 키보드 동작 캡슐화
다음과 같은 훅을 만들었습니다:
- 특정 키를 감지
- 해당 키가 눌렸을 때 액션 실행
- 자동으로 정리(cleanup) 수행
핵심 아이디어는 컴포넌트가 이벤트 리스너가 어떻게 동작하는지 알 필요가 없도록 하는 것입니다. 이제 컴포넌트는 비즈니스 로직처럼 읽히고, 배관 작업은 사라집니다.
useLocalStorage — 자동으로 지속되는 상태
이 훅을 통해 강력한 사실을 배웠습니다: 훅은 상태처럼 보이지만, 상태보다 더 똑똑할 수 있다는 점입니다.
훅의 흐름:
localStorage에서 초기값을 읽음- React 상태와 동기화 유지
- 변화가 있을 때마다 자동 저장
따라서 저장 로직을 곳곳에 작성할 필요 없이 “지속 가능한 상태를 주세요” 라고 선언하면 됩니다. 이는 큰 아키텍처적 업그레이드입니다.
useMovies — 모든 것이 맞물린 순간
이것이 진짜 전환점이었습니다. 다음 책임들을 하나의 훅으로 옮겼습니다:
- 데이터 가져오기(fetch)
- 로딩 상태 관리
- 오류 처리
AbortController사용- 데이터 정리
- 비즈니스 규칙
이제 컴포넌트는 어떻게 데이터를 가져오는지, 어떻게 오류를 처리하는지, 어떻게 레이스 컨디션을 방지하는지 알 필요가 없습니다. 오직 “영화 목록, 로딩, 오류를 주세요” 라는 것만 알면 됩니다. 이런 명확한 관심사의 분리는 컴포넌트를 훨씬 간단하게 만들어 줍니다.
Takeaways
- 커스텀 훅은 앱을 위한 자체 React API 입니다.
useEffect,useState,fetch,addEventListener,localStorage등을 반복해서 쓰는 대신useMovies,useKey,useLocalStorage와 같은 훅을 작성합니다. - 사고 방식이 “어떻게 구현하지?” 에서 “이 동작을 위해 어떤 훅이 필요할까?” 로 바뀝니다.
- Components = UI only
- Hooks = behavior, side effects, logic
- 로직이 재사용 가능하다고 느껴지면 → 훅을 만들어야 합니다.
- 컴포넌트가 무겁게 느껴진다면 → 훅을 추출합니다.
오늘은 커스텀 훅을 이해한 것에 그치지 않았습니다. 새로운 사고 방식으로 구현하기 시작한 날이었습니다. 이제 컴포넌트는 작아졌고, 가장 중요한 것은 저는 이제 단순히 React를 사용하는 것이 아니라, 그 위에 직접 구축하고 있다는 점입니다.