리액트가 훅을 구분하는 방식은 "이름(이름 규칙)"과 "실행 문맥(Execution Context)" 두 가지 단계를 거칩니다.
리액트가 훅을 검출하고 관리하는 메커니즘
1단계: 컴파일 시점의 구분 (이름 규칙: use...)
코드가 실행되기 전, ESLint(개발 도구)는 함수 이름을 보고 훅인지 아닌지 판단합니다.
- 약속된 접두어: 리액트 커뮤니티에서는 모든 커스텀 훅의 이름을 use로 시작하기로 약속했습니다.
- 감시: ESLint는 use로 시작하는 함수를 만나면 "아, 이건 리액트 엔진의 관리를 받아야 하는 훅이구나!"라고 인식하고, 리액트 훅의 규칙(조건문 내 사용 금지 등)을 잘 지키고 있는지 검사합니다.
2단계: 실행 시점의 구분 (Dispatcher와 Call Stack)
진짜 핵심은 실행될 때입니다. 리액트 엔진 내부에는 Dispatcher라는 관리자가 있고, 현재 "누가 실행 중인가"를 기록하는 전역 변수가 있습니다.
- 컴포넌트 렌더링 시작: 리액트가 MyComponent를 호출합니다. 이때 리액트 엔진은 내부적으로 "지금부터 MyComponent 렌더링 시작한다! 훅 대기해!"라고 전역 플래그를 세웁니다.
- 훅 호출 (useQuery 등): 컴포넌트 안에서 훅이 실행됩니다.
- 체크: 훅은 내부적으로 리액트 관리자(Dispatcher)에게 접근합니다. 관리자가 확인해 보니 "방금 MyComponent가 렌더링 시작했다고 했지? 오케이, 넌 정상이야."라고 판단하고 캐시 데이터를 넘겨줍니다.
3단계: 에러가 발생하는 원리 (리액트 밖에서 호출 시)
만약 api/utils.ts 같은 일반 함수 안에서 훅을 호출하면 리액트 엔진은 어떻게 반응할까요?
- 일반 함수 호출: 리액트와 상관없이 그냥 함수가 실행됩니다.
- 훅 호출: 함수 내부의 useQuery가 실행됩니다.
- 관리자 호출: useQuery가 리액트 관리자에게 "데이터 좀 줘!"라고 요청합니다.
- 에러 발생: 관리자가 전역 상태를 확인해 보니 "지금 렌더링 중인 컴포넌트가 없는데? 너 왜 호출됐어?"라고 판단합니다. 이때 발생하는 에러가 바로 Invalid Hook Call입니다.
요약 포인트
리액트가 훅을 구분하는 방법
- 겉모습(이름): use라는 이름으로 시작하는지 본다. (ESLint가 이 단계에서 규칙을 검사함)
- 맥락(Context): 호출된 순간에 "리액트가 컴포넌트를 그리고 있는 중인가?"를 본다. (리액트 엔진이 이 단계에서 런타임 에러를 냄)
'개발' 카테고리의 다른 글
| Complex 컴포넌트 & Headless Hook 아키텍처 정리본 (Table.jsx) (0) | 2026.01.21 |
|---|---|
| 훅과 유틸... hook util의 차이를 아는가 (1) | 2026.01.21 |
| Tanstack Query 관리 구조 (공통 훅 정의) (0) | 2026.01.21 |
| Next.js 정리 — React를 쓰다 보면 반드시 헷갈리는 그 지점들 (0) | 2026.01.20 |
| 전역 관리 vs 로컬 관리 vs API (1) | 2025.08.25 |