프론트엔드 트러블슈팅

[React] Rendered more hooks than during the previous render.

yoxxin 2023. 9. 13. 18:37

에러 캡처

이전 렌더링 때보다 더 많은 훅을 렌더링했다는 뜻.

즉 훅의 호출횟수가 일정하지 않다는 뜻이다.

리액트 훅은 컴포넌트 내부 최상위 레벨에 선언해야한다.

즉 훅은 컴포넌트를 제외하고는 다른 블럭({ }) 내부에서 이용해서는 안된다

 

훅을 다음과 같이 선언하지는 않았는지 확인해보자.

// 전부 잘못된 훅 호출 방식이다
// 1. 조건문 안에서 호출
if (someCondition) {
  useEffect(() => {
    ... 
  });
}

// 1.1 && 연산자 이용하여 조건부 호출
!value && useCustomHook(value)

// 2. 반복문 안에서 호출
items.forEach(item => {
  useEffect(() => {
    ...
  });
});

// 3. 이벤트 핸들러나 다른 함수 내에서 호출
function handleEvent() {
  useEffect(() => {
    ...
  });
}

만약 그렇다면 이렇게 바꿔주자.

// 1. 조건문 안에서 호출X
useEffect(() => {
  if (someCondition) {
    ...
  }
});

// 1.1 && 연산자 이용하여 조건부 호출
// 대신 CustomHook 내부에서 null 검사하자
// useCustomHook.ts
const useCustomHook(value?: string) => {
  // 여기에 널 검사를 추가하면, useEffect 호출 여부가 달라지므로 에러해결이 안된다.
  useEffect(() => {
    if(!value) return; // 널 검사
    ...
  },[])
  ...
}
// Component.tsx
const Component = () => {
  useCustomHook(value);
  ...
}

// 2. 반복문 안에서 호출X
useEffect(() => {
  items.forEach(item => {
    ...
  });
});