규칙은 왜 필요한가?

322025년 09월 16일4

use 접두사라는 약속이 정해졌지만, 소피는 여전히 마음 한편이 불안했다. 그녀는 개발자들이 단순히 이름 짓기 규칙만으로 훅의 복잡한 메커니즘을 온전히 이해할 수 있을지 확신이 서지 않았다.

“우리는 사람들에게 ‘왜’ 이 규칙들이 필요한지 근본적인 이유부터 설명해야 합니다.”
그녀는 회의에서 팀원들에게 강조했다.
“단순히 ‘하지 마세요’라고 말하는 것은 효과가 없어요. 그 이면에 있는 ‘어떻게’와 ‘왜’를 이해시켜야만, 개발자들이 진심으로 규칙을 따르게 될 겁니다.”

그녀의 말은 정곡을 찔렀다.
훅의 마법은 ‘호출 순서의 불변성’이라는, 보이지 않는 하나의 약속 위에 아슬아슬하게 서 있었다. 이 약속이 깨지는 순간, 모든 것이 무너져 내렸다.

댄은 소피의 의견에 전적으로 동의했다. 그는 개발자들이 훅의 멘탈 모델을 명확하게 구축할 수 있도록, 규칙의 배경을 설명하는 작업에 착수했다.

그가 설명의 핵심으로 삼은 것은 바로 useState의 내부 동작 원리였다.
그는 다시 한번, 리액트가 훅의 상태를 어떻게 관리하는지에 대한 단순화된 모델을 화이트보드에 그렸다.

React’s Internal Memory

// BlogPost 컴포넌트 렌더링 중...
memoizedState: [
  'Hello World', // 첫 번째 useState의 상태
  true, // 두 번째 useState의 상태
  'Technology', // 세 번째 useState의 상태
];

“리액트는 컴포넌트별로 이런 간단한 배열을 가지고 있다고 상상해 보세요.”
댄이 설명했다.
“여러분이 useState를 호출할 때, 리액트는 이 배열에서 순서대로 값을 꺼내줍니다. 첫 번째 useState는 0번 인덱스의 값을, 두 번째 useState는 1번 인덱스의 값을 가져가죠.”

여기까지는 모두가 이해하고 있는 내용이었다.

“이제, 소피가 지적했던 문제를 다시 봅시다. 만약 두 번째 useState를 조건문 안에 넣으면 어떻게 될까요?”

function BlogPost() {
  const [title, setTitle] = useState('Hello World'); // 0번 인덱스

  let isPublished, setIsPublished;
  if (title !== '') {
    [isPublished, setIsPublished] = useState(true); // 1번 인덱스?
  }

  const [category, setCategory] = useState('Technology'); // 2번 인덱스?
  // ...
}

“첫 번째 렌더링에서는 title이 비어있지 않으니, if문이 실행됩니다. isPublished는 1번 인덱스, category는 2번 인덱스의 상태를 정상적으로 받아오죠.”

“하지만 사용자가 title을 모두 지워서 빈 문자열로 만들었다고 가정해 봅시다. 리렌더링이 발생합니다.”

During Re-render (when title is "")

  1. 첫 번째 useState가 호출됩니다. 리액트는 0번 인덱스의 "" 값을 반환합니다.
  2. if (title !== "") 조건문은 이제 거짓(false)이 됩니다. isPublished를 위한 useState는 호출되지 않습니다.
  3. 세 번째 useState가 호출됩니다. 이것은 코드상으로는 세 번째지만, 이번 렌더링에서는 두 번째로 호출된 useState입니다.
  4. 리액트는 두 번째 호출이므로, 1번 인덱스의 상태를 꺼내주려고 합니다.
  5. 하지만 1번 인덱스에는 isPublished의 상태인 true가 저장되어 있습니다.
  6. 결과적으로, category 변수는 엉뚱하게도 true라는 값을 할당받게 됩니다. 상태가 서로 뒤섞여 버린 겁니다.

댄의 설명은 명확했다.
훅의 순서가 렌더링마다 달라지는 순간, 리액트는 어떤 상태가 어떤 useState 호출에 해당하는지 구분할 방법이 완전히 사라져 버렸다.

“이것이 바로 우리가 규칙을 만들어야만 하는 이유입니다.”
댄이 결론지었다.
“훅은 마법이 아닙니다. 그저 호출 순서에 의존하여 배열의 인덱스를 맞춰보는, 지극히 단순하고 예측 가능한 시스템일 뿐입니다. 이 시스템이 깨지지 않게 하려면, 우리는 이 순서를 절대 바꾸지 않겠다고 리액트와 약속해야만 합니다.”

이 설명은 ‘왜’라는 질문에 대한 명쾌한 답이었다.
규칙은 개발자를 억압하기 위한 족쇄가 아니었다. 오히려 훅이라는 강력한 도구를 안전하게 사용하기 위해, 개발자 스스로를 보호하는 안전장치였다.

이제 팀은 이 근본적인 원리를 바탕으로, 모든 개발자가 따라야 할 두 개의 명확하고 구체적인 규칙을 성문화할 준비가 되었다.
그것은 훅의 세계를 지배하는 대헌장이 될 터였다.