[React Error] Invalid Hook Call Error

고병표·2022년 9월 17일
0

Error 모음

목록 보기
12/13

Outlook add in 을 React로 리뉴얼 하는 프로젝트에서 해당 에러가 발생하였다.

Hooks을 호출할 때 발생한 에러로 확인했고. 리액트 공식 홈페이지에서 해당 에러는 세 가지 정도의 이유를 확인할 수 있었다.

1. Mismatching Versions of React and React DOM

프로젝트의 react-dom의 버젼이 Hook을 사용할 수 있는 버젼인 16.8.0보다 낮을 때 이러한 에러가 발생한다.

해당 프로젝트는 React 17 버전을 사용하고 있어 이 부분은 에러가 아님을 확신할 수 있었다.

2. Breaking the Rules of Hooks

Hooks를 호출할 때는 함수형 component의 최상위 부분에서 호출해야 한다.

다른 경우, 이를테면

1. 클래스형 component 안에서 호출 하는 경우

class Bad1 extends React.Component {
	render() {
    	useEffect(() => {})
    }
}

2. event handler 안에서 호출 하는 경우

function Bad2() {
  function handleClick() {
    const theme = useContext(ThemeContext);
  }
}

3. useMemo, useReducer, 혹은 useEffect 에 전달 된 함수 내에서 호출 하는 경우

function Bad3() {
  const style = useMemo(() => {
    const theme = useContext(ThemeContext);
    return createStyle(theme);
  });
}

위와 같은 세가지 경우와 같이 Hook을 호출 했다면 에러가 발생할 것이다.

  const dispatch = useDispatch();
  const userEmail = useSelector((state) => state.user.userId);
  const isLogin = useSelector((state) => state.user.isLogin);

  const handleClick = () => {
    useCallback(() => dispatch(logoutUser()), [dispatch]);
    useCallback(() => dispatch(clearHistory()), [dispatch]);
  };

내가 작성한 코드는 handleClick 안에 useCallback을 사용하고 dispatch 를 사용했다. 때문에 해당 에러가 발생하였다.

  const dispatch = useDispatch();
  const userEmail = useSelector((state) => state.user.userId);
   const isLogin = useSelector((state) => state.user.isLogin);

  const logoutHandle = useCallback(() => dispatch(logoutUser()), [dispatch]);
  const clearHandle = useCallback(() => dispatch(clearHistory()), [dispatch]);

  const handleClick = () => {
    logoutHandle;
    clearHandle;
  };

코드를 다음과 같이 수정하여 해당 에러를 해결하였다.

3. Duplicate React

해당 에러는 "Hooks가 제대로 작동하려면 내 어플리케이션의 코드의 import와 react-dom의 import가 같은 모듈로 해석되어야 한다.

만일 다른 두 개의 export 객체로 해석하게 된다면 결국 두 개의 react package가 복사된 경우가 발생할 수 있다" 로 할 수 있었다.

쉽게 말하년 npm ls react를 해서 하나 이상의 react가 있나 확인해야 한다.


어떻게 보면 기본기일 수도 있어 아쉬운 문제였다.
공식 문서를 잘 읽어야겠다.

0개의 댓글