커스텀 훅이라는 개념이 정립되자, 팀은 곧바로 새로운 문제에 봉착했다.
화면에 떠 있는 useWindowWidth
함수를 보고 있던 한 개발자가 질문을 던졌다.
“이 useWindowWidth
함수와, 그냥 일반적인 유틸리티 함수를 리액트나 다른 개발자들이 어떻게 구분할 수 있을까요?”
그의 질문은 타당했다.
useWindowWidth
는 겉보기에는 평범한 자바스크립트 함수였다. 하지만 그 내부에서는 useState
와 useEffect
를 호출하고 있었다. 이것은 이 함수가 리액트의 ‘규칙’을 따라야 함을 의미했다. 즉, 컴포넌트의 최상위 레벨에서만 호출되어야 하고, 다른 커스텀 훅이나 함수형 컴포넌트 안에서만 사용될 수 있다는 제약이 있었다.
반면, 두 숫자를 더하는 add(a, b)
같은 일반 유틸리티 함수는 아무 데서나 자유롭게 호출할 수 있었다.
“만약 어떤 개발자가 커스텀 훅을 일반 함수로 착각하고, 컴포넌트 바깥의 전역 스코프에서 호출하려고 시도하면 어떻게 되죠?”
결과는 뻔했다.
리액트의 렌더링 컨텍스트 밖에서 useState
를 호출하려는 시도이므로, 에러가 발생하며 앱이 멈출 터였다.
“우리에겐 약속이 필요합니다. 개발자가 한눈에 ‘아, 이것은 리액트의 규칙을 따르는 특별한 함수구나’라고 알아차릴 수 있는 신호 말입니다.”
팀은 네이밍 컨벤션, 즉 이름 짓기 규칙을 만들기로 했다.
다양한 아이디어가 오고 갔다.
hook_
으로 시작하기? on
으로 시작하기?
결론은 이미 그들 가까이에 있었다.
useState
, useEffect
.
그들이 이미 만든 코어 훅들은 모두 use
라는 동사로 시작하고 있었다.
“모든 커스텀 훅은 use
로 시작하도록 규칙을 정하는 겁니다.”
댄이 제안했다.
“useWindowWidth
, useInput
, useFetch
처럼요. 이 use
라는 접두사가 바로, 그 함수가 ‘훅’이라는 것을 알려주는 명백한 신호가 되는 거죠.”
이 결정은 단순한 스타일 가이드를 넘어, 훨씬 더 깊은 의미를 가졌다.
이 use
접두사는 사람뿐만 아니라, ‘기계’를 위한 신호이기도 했다.
앞서 논의되었던 린트(Lint) 플러그인 개발 아이디어가 다시 수면 위로 떠올랐다. 린트 플러그인이 훅의 규칙 위반을 자동으로 검사하려면, 어떤 함수가 훅인지 아닌지를 먼저 식별해야만 했다. use
접두사는 바로 그 식별자의 역할을 할 수 있었다.
린트 플러그인은 이렇게 작동할 터였다.
- 이름이
use
로 시작하고 첫 글자가 대문자인 함수(예:useState
,useEffect
)는 리액트의 내장 훅이라고 인식한다. - 이름이
use
로 시작하고 첫 글자가 소문자인 함수(예:useWindowWidth
)는 커스텀 훅이라고 인식한다. - 그리고 이 두 종류의 함수(훅)가, 조건문이나 반복문 안에서 호출되거나, 일반 함수 안에서 호출되면 즉시 개발자에게 경고를 보낸다.
use
라는 단순한 접두사 하나가, 인간 개발자와 자동화된 도구 사이의 중요한 소통 채널이 된 것이다. 그것은 단순한 작명 규칙이 아니라, 새로운 패러다임이 안정적으로 동작하기 위한 핵심적인 안전장치였다.
이제 남은 것은 이 규칙들을 명문화하고, 모든 개발자가 따라야 할 ‘율법’으로 만드는 일이었다. 커뮤니티가 혼란에 빠지지 않도록, 훅의 힘을 올바르게 사용하도록 이끌어줄 명확한 가이드라인이 필요했다.
리액트 팀의 다음 과제는 ‘훅의 규칙(Rules of Hooks)’을 제정하는 것이었다.
그것은 훅의 세계를 지탱하는, 두 개의 깨뜨릴 수 없는 계명이 될 터였다.