TechFeedTechFeed
React런타임

React Hook 규칙 위반 — Rules of Hooks

React Hook "useX" is called conditionally. / called in function that is neither a component nor a custom hook
한 줄 해결: 훅을 조건문·반복문·일반 함수 안에서 호출해 발생하며, 훅은 컴포넌트/커스텀 훅 최상위에서 항상 같은 순서로 호출해야 합니다.

이런 증상일 때

eslint-plugin-react-hooks 경고 또는 런타임에서 훅 호출 순서가 바뀌어 동작이 깨집니다. if문 안의 useState, 콜백 안의 useEffect가 대표적입니다.

원인

  • 조건문/반복문/중첩 함수 안에서 훅 호출
  • 일반 함수(컴포넌트도 커스텀 훅도 아닌)에서 훅 사용
  • early return 이후에 훅 호출(조건부 호출과 동일)

해결 방법

1
훅은 최상위에서

모든 훅을 컴포넌트 함수 최상단에서 무조건 호출하고, 조건은 훅 내부나 반환부에서 처리합니다.

const [v, setV] = useState(0)
useEffect(() => { if (cond) doSomething() }, [cond]) // 조건은 안에서
2
early return은 훅 뒤로

조건부 렌더링의 return은 모든 훅 호출 다음에 둡니다.

3
로직은 커스텀 훅으로

훅을 쓰는 로직을 재사용하려면 use로 시작하는 커스텀 훅으로 추출합니다.

function useUserData(id) { const [d, setD] = useState(null); /* ... */ return d }
💡 예방: eslint-plugin-react-hooks의 rules-of-hooks와 exhaustive-deps 규칙을 켜두면 대부분 작성 단계에서 잡힙니다.
ReactHooksrules of hooksuseEffecteslint

관련 에러

관련 가이드

하이드레이션 미스매치, Hydration failed, 서버 클라이언트 불일치 | 콘솔에 빨간 줄이 뜨면 뭐부터 볼까?error.tsx, not-found, global-error, digest | 없는 글인데 500이 뜨면?after, waitUntil, 응답 후 작업, 페이지뷰 | 문의 저장이 끝났는데 버튼이 안 풀리면?useFormStatus, useActionState, 이중 제출, 서버 액션 | 문의 버튼이 두 번 눌리면?