본문 바로가기
React

Rendered more hooks than during the previous render

by kicksky 2021. 3. 28.

// 컴포넌트 내부
const { loading: loadingAll, data: dataAll, error: errorAll } = useQuery(
    GET_KINDERGARTENS
  );
const [type, setType] = useState<string>("");

if (loadingAll) return <p>Loading</p>;
if (errorAll) return <p>ERROR</p>;
if (!dataAll) return <p>Not found</p>;

useEffect(() => {
    if (!type.length) return;
    const filteredArray = filterByType(dataAll.kindergartens, type).map(
      (item: any) => {
        return {
          name: item.name,
          location: { long: item.long, lat: item.lat },
        };
      }
    );
    coordVar([...filteredArray]);
}, [type]);

return ( ... )

이 에러는 코드 배치의 문제였다.

 

(1) useQuery가 데이터를 불러오기 전까지는 loading 값이 true라서 <p>Loading</p>가 바로 리턴이 되고 그 밑의 useEffect Hook이 실행되지 않는다.

(2) 그런데 데이터 로드가 끝나고 loading이 false가 되면서 다시 렌더링이 되면 그 밑의 코드들, 즉 useEffect Hook이 호출되고 맨 밑의 return이 마저 렌더링 된다. 

 

(1)과 (2)에서 각각 호출되는 Hook의 순서(혹은 개수)가 달라지면서 에러가 발생한다.

 

리액트 문서 Hook의 규칙에 나와있듯 early return이 문제의 원인이었다. 리액트가 Hook이 호출되는 순서에 의존하기 때문에 이를 지켜주어야 하고, 컴포넌트 최상위에 Hook을 정의하라는 규칙도 이와 관련된다.

 


ko.reactjs.org/docs/hooks-rules.html#explanation

(stackoverflow.com/questions/57560352/rendered-more-hooks-than-during-the-previous-render)

 

'React' 카테고리의 다른 글

forwardRef  (0) 2021.11.22
Lazy-loading  (0) 2021.05.08
Kakao Map API에서 마우스 이벤트 핸들링  (0) 2021.04.07
Brad Westfall, React: "mount" vs "render"  (0) 2021.02.13

댓글