2026. 7. 18.

Invalid hook call이 뜨면 코드를 고칠까, 패키지를 고칠까?

React Invalid hook call 경고를 Hook 호출 규칙, React와 React DOM 버전, 중복 React 경로로 나눠 확인하고 최소 수정 뒤 재검증하는 순서다.

3 min read
Invalid hook call이 뜨면 코드를 고칠까, 패키지를 고칠까? 대표 이미지

Hooks can only be called inside the body of a function component가 뜨면 Hook 코드를 전부 옮기거나 node_modules부터 지우지 않는다. React 공식 문서가 제시하는 흔한 원인은 Hook 규칙 위반, React와 React DOM 버전 불일치, React 중복 설치 세 갈래다.

가장 되돌리기 쉬운 확인부터 한다. Hook 호출 위치를 보고, 문제가 없으면 npm ls react react-dom으로 버전과 의존성 경로를 읽는다. 세 갈래 중 하나를 증거로 고른 뒤 그 부분만 수정하는 것이 핵심이다.

React 콘솔의 Invalid hook call 경고 앞에서 코드 위치와 패키지 트리 중 확인할 곳을 고르는 개발 상황

먼저 세 갈래로 나눈다

확인 순서보이는 단서다음 행동
1. Hook 위치조건문, 반복문, 이벤트 함수, 일반 함수 안에서 Hook 호출컴포넌트나 커스텀 Hook 최상위로 이동
2. 버전reactreact-dom 버전이 프로젝트 기대와 다름package.json과 설치 트리를 맞춰 다시 설치
3. 중복 설치서로 다른 경로에 React가 잡히거나 링크된 라이브러리가 별도 React를 가짐React를 끌어오는 패키지 경로부터 정리

이 순서는 설치를 크게 바꾸기 전에 코드 한 줄로 끝날 문제를 먼저 걸러낸다. 반대로 코드가 규칙을 지키는데도 파일만 계속 옮기는 낭비도 막는다.

1. Hook 호출 위치부터 확인한다

React의 Rules of Hooks는 Hook을 함수 컴포넌트 또는 커스텀 Hook의 최상위에서 호출하라고 안내한다. 조건문, 반복문, 중첩 함수, 이벤트 핸들러, try/catch 안에서 호출하면 렌더마다 Hook 순서가 달라질 수 있다.

아래 코드는 enabled가 참일 때만 useEffect를 호출한다. 조건을 Hook 바깥으로 옮겨 호출 순서를 고정한다.

// 잘못된 위치
function Profile({ enabled }) {
  if (enabled) {
    useEffect(() => {
      connectProfile();
    }, []);
  }
  return <section>프로필</section>;
}
// 호출 순서는 고정하고 조건은 Effect 안에서 판단
function Profile({ enabled }) {
  useEffect(() => {
    if (!enabled) return;
    return connectProfile();
  }, [enabled]);

  return <section>프로필</section>;
}
React Hook을 호출해도 되는 컴포넌트 최상위와 조건문·이벤트 안의 금지 위치를 대비한 비공식 코드 도식

이벤트가 발생한 뒤 상태를 바꾸려는 목적이라면 이벤트 함수 안에서는 Hook이 아니라 이미 만든 setter를 호출한다.

function Counter() {
  const [count, setCount] = useState(0);

  function handleClick() {
    setCount(value => value + 1);
  }

  return <button onClick={handleClick}>{count}</button>;
}

경고와 함께 반복 렌더가 보인다면 Maximum update depth 확인 순서로 이어서 상태 업데이트가 렌더를 다시 부르는지도 구분한다.

2. React와 React DOM 버전을 함께 본다

코드 위치가 규칙을 지키면 프로젝트 루트에서 설치 상태를 출력한다. 이 명령은 파일을 바꾸지 않고 설치된 버전과 논리 의존성 경로를 보여 준다.

npm ls react react-dom

package.json에 선언한 범위, 실제 출력된 버전, reactreact-dom 조합을 함께 본다. 공식 경고 문서는 지원하지 않는 renderer 버전도 원인 갈래로 제시한다. 여기서 중요한 것은 무조건 최신 버전으로 올리는 일이 아니라 프로젝트가 쓰려는 조합과 실제 설치 결과가 같은지 확인하는 것이다.

버전을 바꿨다면 사용 중인 패키지 관리자로 설치를 다시 맞추고 개발 서버를 재시작한다. 오류를 피하려고 서로 다른 패키지 관리자의 lockfile을 섞어 만들지는 않는다.

3. React 중복 경로를 좁힌다

버전 숫자가 비슷해도 앱 코드와 react-dom이 서로 다른 React 모듈을 읽으면 같은 경고가 날 수 있다. React의 Invalid Hook Call 안내는 Node 패키지 환경에서 npm ls react로 복수 React를 확인하라고 제시한다.

npm ls react --all

npm ls 공식 문서에 따르면 이 출력은 실제 폴더 목록이 아니라 논리 의존성 트리다. 따라서 여러 줄이 보인다는 이유만으로 모두 지우지 않는다. 다른 버전이 어느 라이브러리 아래에 들어왔는지, 로컬 npm link나 workspace가 별도 React를 갖는지부터 확인한다.

필요하면 원인을 끌어온 경로를 아래 명령으로 거꾸로 본다.

npm explain react
터미널의 React 의존성 트리와 코드 위치·버전·중복·재검증 네 단계가 함께 보이는 비공식 점검 화면

AI에게 수정을 맡길 때도 Invalid hook call 해결해줘만 보내지 않는다. 증거와 수정 범위를 함께 준다.

이 React 앱에서 Invalid hook call이 재현됩니다.
1) Hook이 조건·반복·중첩 함수 안에서 호출되는지 먼저 확인하세요.
2) 아래 npm ls 출력에서 react와 react-dom 버전, 중복 경로를 구분하세요.
3) 원인 한 갈래만 고르고 필요한 파일 또는 의존성만 최소 수정하세요.
4) 수정한 파일과 재검증 명령을 마지막에 적으세요.

Next.js에서 Hook을 쓰는 파일이 Server Component라면 패키지 문제가 아니라 경계 문제일 수 있다. 그 경우에는 use client를 붙일 파일을 고르는 순서를 먼저 확인한다.

수정 후 같은 동작으로 재검증한다

수정은 경고 문구를 숨기는 데서 끝나지 않는다.

  1. 개발 서버를 다시 시작한다.
  2. 경고가 났던 URL과 클릭·입력 동작을 그대로 재현한다.
  3. 화면이 기대한 상태로 바뀌는지 본다.
  4. Console에서 Invalid hook call이 사라졌는지 확인한다.
  5. npm ls react react-dom 출력이 의도한 버전과 경로인지 저장한다.

Hook 규칙, UI 동작, 패키지 출력 세 증거가 함께 맞아야 해결이다. 세 갈래를 모두 확인했는데도 경고가 남으면 기능을 작은 컴포넌트로 줄여 최소 재현을 만든다. 공식 문서도 다른 원인에서는 재현 가능한 예를 준비해 확인할 것을 권한다.

공식 확인 자료

이 글은 AI 코딩과 개발 학습의 일반 정보 제공 목적입니다. 도구, 모델, 커리큘럼, 요금은 버전과 시점에 따라 달라질 수 있으므로 실습이나 도입 전 공식 문서와 최신 릴리스 노트를 확인하세요.

다음으로 읽을 기사

같은 흐름으로 이어 읽기 좋은 기사만 추려 보여줍니다.

댓글 0

이 글을 읽은 독자들의 생각을 나눠보세요.

비밀번호(선택)

첫 번째 댓글을 남겨보세요

여러분의 생각이 다른 독자에게 도움이 됩니다.