개발일지/React

[에러해결] Invalid Hook Call Error

hangooksaram 2020. 9. 14. 16:10

음악 관리 프로그램에서 며칠 전부터 Invalid Hook Call(유효하지 않은 Hook을 요청)하고 있다며 에러가 발생해 구동되지 않았다.

 

useEffect(() => {
    callApi()
      .then(res => setMusics(res))  // 에러가 발생한 부분
      .catch(err => console.log("this is error " + err));
  }, [])



  const callApi = async() => {
    const response = await fetch('http://localhost:5000/musicdata')
    const body = await response.json();
    return body;
  }

 

setMusics에서 Hooks을 호출할때 에러가 발생한 것 같았다. 인터넷에 에러를 검색하니 리액트 공식 홈페이지에 해당 에러가 검색되었고 들어가서 보통 세가지정도의 이유로 이 에러가 발생한다는 것을 알 수 있었다.

 

1. Mismatching Versions of React and React DOM

 

react-dom의 버젼이 Hook을 사용할 수 있는 버젼인 16.8.0보다 낮을 때 이러한 에러가 뜰 수 있다. 

 

package.json을 확인했을 때 위와 같이 16.8.0보다 높음을 확인했다. 그리고 따로 react 버전을 바꾼적이 없어 이부분은 에러가 아님을 확신할 수 있었다.

 

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을 호출 했다면 에러가 발생할 것이다. 내 App.js는 함수형 component로 작성이 되었고 위의 코드를 보다시피 event handler안에 호출 되지도, 3번같은 형식으로 호출되지도 않았기 때문에 2번의 경우도 아닌것을 확인했다.

 

3. Duplicate React

 

우선 이 경우가 내 에러에 해당되는 상황임을 확인 할 수 있었다. 해석을 해보자면 "Hooks가 제대로 작동하려면 내 어플리케이션의 코드의 import와 react-dom의 import가 같은 모듈로 해석되어야 한다. 만일 다른 두개의 export 객체로 해석하게 된다면 결국 두개의 react package가 복사된 경우가 발생 할 수있다" 로 할 수 있었다. 맥락상 무슨 의미인줄은 알겠으나 솔직히 정확하게 뭘 뜻하는지는 알지 못했다. 우선 해결 방법으로 npm ls react를 해서 하나 이상의 react가 있나 확인해야 했다.

 

 

위에 보이는 며칠 전 react-star-ratings 라는 모듈은 음악을 추가할때 들어가는 속성중 rate의 input으로 넣기위해 다운받았던 모듈이다. 매우 어이가 없었다. 위의 사진 처럼 react가 발견이 되었고 나는 저 모듈을 삭제했다. 이로써 이 에러는 해결이 되었다.

 

며칠동안 무엇이 문제일까 검색하며 고민했던 문제인데 너무 어이가 없었다. 다시한번 공식 문서를 잘 읽어보는 것이 정말 좋은 방법이라는 것을 느꼈다.