인간은 실수를 반복한다

352025년 09월 19일3

‘훅의 규칙’이 명문화되었다.
두 개의 단순하고 강력한 원칙은 훅의 세계에 질서를 가져왔다. 이론적으로, 개발자들은 이제 이 규칙들을 따르기만 하면 모든 것이 해결될 터였다.

하지만 댄 아브라모프의 마음은 편치 않았다.
그는 Redux를 만들고, 수많은 개발자 커뮤니티와 소통하면서 한 가지 명백한 진리를 깨달았다.
‘인간은 실수를 반복한다.’

아무리 문서에 명확하게 경고하고, 블로그에 상세하게 설명해도, 개발자들은 실수를 저질렀다. 마감에 쫓기거나, 피곤하거나, 혹은 단순히 개념을 완벽하게 이해하지 못해서, 그들은 규칙을 어기곤 했다.

댄은 동료 개발자가 겪게 될 미래를 생생하게 그릴 수 있었다.

어느 늦은 밤, 한 개발자가 복잡한 로직을 구현하다 무심코 useEffectif문 안에 넣을 것이다. 로컬 환경에서는 모든 것이 정상적으로 작동하는 것처럼 보일 것이다. 특정 조건이 항상 참이었기 때문이다.

그는 코드를 커밋하고, 코드는 프로덕션 환경에 배포될 것이다.
그리고 며칠 뒤, 특정 사용자 그룹에서만 간헐적으로 발생하는, 도무지 원인을 알 수 없는 버그 리포트가 쏟아지기 시작할 것이다.

버그를 추적해야 하는 개발자는 지옥을 맛보게 될 터였다.
에러 메시지는 명확한 원인을 알려주지 않고, 그저 상태 값이 엉뚱하게 바뀌었다는 현상만 보여줄 것이다. 그는 컴포넌트의 모든 로직을 의심하며 수많은 console.log를 찍고, 몇 시간, 혹은 며칠을 허비한 끝에야 자신이 ‘훅의 규칙’을 어겼다는 사실을 깨닫게 될 것이다.

이런 시나리오는 상상이 아니었다. 그것은 명백히 일어날 미래였다.

“문서만으로는 부족합니다.”
댄이 팀 회의에서 단호하게 말했다.
“우리가 아무리 ‘왜’ 규칙이 필요한지 설명해도, 모든 개발자가 그것을 항상 기억하고 지킬 것이라고 기대할 수는 없습니다. 우리는 개발자의 선의나 집중력에 의존해서는 안 됩니다.”

그의 말에는 개발자들의 고통을 미리 막아주고 싶어 하는 깊은 공감이 담겨 있었다.
“우리는 시스템적으로 이 문제를 해결해야 합니다. 개발자가 실수를 저지르는 바로 그 순간, 그의 어깨를 두드리며 ‘잠깐만요, 이건 규칙 위반입니다’라고 알려주는 자동화된 장치가 필요합니다.”

소피가 그의 말에 동의했다.
“마치 자동차의 안전벨트 경고음 같군요. 벨트를 매지 않으면 계속 소리를 내서, 운전자가 규칙을 따르도록 만드는 거죠.”

“정확합니다.”
댄이 고개를 끄덕였다. “우리에겐 훅을 위한 안전벨트 경고음이 필요합니다.”

그들이 이미 어렴풋이 구상했던 아이디어, 린트(Lint) 플러그인이 다시 한번 논의의 중심에 섰다. 린트(Linter)는 코드를 분석하여 잠재적인 오류나 스타일 위반을 찾아주는 도구였다. 대부분의 개발자들은 ESLint와 같은 린터를 코드 에디터에 설치하여, 코드를 작성하는 실시간으로 피드백을 받고 있었다.

만약 리액트 팀이 ‘훅의 규칙’을 검사하는 공식 ESLint 플러그인을 만들어 제공한다면?
개발자가 조건문 안에 useState를 쓰는 순간, 그의 코드 에디터에는 즉시 빨간 밑줄이 그어지고 경고 메시지가 나타날 것이다. 버그가 만들어지기도 전에, 코드가 저장되기도 전에 실수를 바로잡을 수 있게 되는 것이다.

이것은 훅의 성공을 위한 필수적인 마지막 퍼즐 조각이었다.
훅의 힘이 강력한 만큼, 그 힘을 안전하게 제어할 장치도 그만큼 강력해야 했다.

팀의 목표는 이제 명확해졌다.
단순히 훅이라는 기능을 만드는 것을 넘어, 개발자들이 그 기능을 올바르게 사용하도록 이끄는 ‘완벽한 경험’을 설계하는 것.

그들의 다음 과제는, 이 보이지 않는 파수꾼, 코드의 세계를 지키는 충실한 문지기를 창조하는 일이었다.