Invalid Hook Warning은 react hook을 이용하다 보면 자주 발생하는 문제로 React 공식 문제에서도 해당 문제에 대한 해결법을 정리해두었습니다. 필요하신 분은 아래 공식 사이트를 이용하셔도 됩니다.
React 공식 문서 - Invalid Hook Warning
https://ko.legacy.reactjs.org/warnings/invalid-hook-call-warning.html
1. Invalid Hook Call Warning은 언제 발생할까?
Hooks can only be called inside the body of a function component.
(Hooks는 함수 컴포넌트의 본문 내에서만 호출할 수 있습니다.)
에러 메세지에서도 알 수 있듯 hook을 잘못 사용한 경우에 발생하며, 그 위치와 큰 관련이 있습니다. 일반적으로 해당 메세지를 마주치게 되는 상황은 다음과 같습니다.
- React와 React DOM의 버전이 일치하지 않는 경우
- Hooks 규칙을 위반하는 경우
- 같은 앱에 React가 한 개 이상 있는 경우
사실 가장 많이 접하게 되는 경로는 2번, Hooks 규칙을 위반하는 경우입니다.
2. Invalid Hook Call Warning 해결 방법
2.1. React와 React DOM의 버전 불일치
React hooks이 도입되기 이전 버전으로 프로젝트가 생성된 경우에도 발생할 수 있습니다. react-dom(<16.8.0)의 버전을 사용하고 있는 경우에는 그 이상의 버전으로 업그레이드를 해야합니다.
현재 프로젝트의 React DOM 버전은 아래 명령어로 확인할 수 있습니다.
$ npm ls react-dom
2.2. Hooks 규칙 위반
Hooks는 함수 컴포넌트를 렌더링하는 동안에만 호출할 수 있습니다.
- 👍 함수 컴포넌트 본문의 최상위 레벨에서 호출
- 👍 사용자 정의 Hook 본체의 최상위 레벨에서 호출
const Counter = () => {
// ✅ 권장: 함수 컴포넌트의 최상위 레벨
const [count, setCount] = useState(0);
...
}
const useWindowWidth = () => {
// ✅ 권장: 사용자 정의 Hook의 최상위 레벨
const [width, setWidth] = useState(window.innerWidth);
...
}
Hooks 사용에 대하여 혼란을 주지 않기 위하여 React에서는 위 두 가지 경우를 제외한 나머지에 대한 호출은 지원하지 않습니다.
- 👎 클래스 컴포넌트에서 Hooks를 호출하는 경우
- 👎 이벤트 핸들러에서 호출하는 경우
- 👎 useMemo, useReducer 또는 useEffect에 전달된 함수 내에서 Hooks를 호출하는 경우
function Bad1() {
function handleClick() {
// 🔴 금지: 이벤트 핸들러 내에서 사용 (고치려면 바깥으로 옮기세요!)
const theme = useContext(ThemeContext);
}
// ...
}
function Bad2() {
const style = useMemo(() => {
// 🔴 금지: useMemo 안에서 사용 (고치려면 바깥으로 옮기세요!)
const theme = useContext(ThemeContext);
return createStyle(theme);
});
// ...
}
class Bad3 extends React.Component {
render() {
// 🔴 금지: 클래스 컴포넌트 안에서 사용
useEffect(() => {})
// ...
}
}
저의 경우에도 Invalid Hook Call Warning이 발생한 이유가 이벤트 핸들러 내(logout 내)에서 Hook, useNavigate를 호출하였기 때문이었습니다.
const SettingScreen = () => {
const logout = () => {
const navigate = useNavigate();
const cookies = new Cookies();
// 인증 관련 토큰 제거
cookies.remove("accessToken");
cookies.remove("refreshToken");
// 자동 로그인 설정 제거
cookies.remove("autoLogin");
navigate("/");
};
...
}
지침대로 useNavigate를 logout 바깥으로 옮기는 것으로 간단하게 문제를 해결할 수 있었습니다.
2.1. React 중복
Hooks가 작동하려면 애플리케이션에서 가져온 'react'가 'react-dom' 패키지 내부에서 가져온 'react' 모듈과 동일하여야 한다는 조건이 있습니다.
이 두 개의 react가 서로 다르다면 Invalid Hook Call Warning이 발생한다고 합니다. react 패키지의 두 복사본이 있는 지를 확인하여 문제를 해결할 수 있습니다.
'Web > React' 카테고리의 다른 글
[React] React에서 API 호출을 효과적으로 막는 방법 - useRef 활용하기 (0) | 2024.11.22 |
---|---|
[React] Warning: React has detected a change in the order of Hooks 에러 해결하기 (0) | 2024.07.17 |
[React] 접근 제한을 위한 Private Route 만들기 (0) | 2024.04.21 |
[Recoil] React를 위한 상태 관리 라이브러리, Recoil에 대하여 알아보자 (2) | 2024.02.07 |
[React + Vite] "Failed to load resource: the server responded with a status of 404(not found)" 해결하기 (0) | 2023.11.16 |