트러블슈팅

[React] Error: Rendered more hooks than during the previous render 에러 해결하기

emmaOH! 2025. 1. 7. 22:14

🌵 문제 상황

사용자가 특정 유저를 클릭하면 'https://es-cape-codeit.vercel.app/user/616'와 같이 마지막에 유저 아이디가 포함된 url로 이동합니다.

해당 페이지는 유저의 프로필을 볼 수 있는 페이지입니다.

 

현재 유저 페이지의 url에서 유저 아이디를 가져와 if문으로 아이디의 유효성을 검사한 뒤, 유효하지 않다면 에러를 띄워 홈 화면으로 돌아가도록 구현하려고 하였습니다.

 

따라서 생각의 흐름과 동일하게 페이지로 이동했을 때 바로 아이디의 유효성을 검사하도록 if문을 가장 위에 두고,

이후에 컴포넌트 렌더링에 필요한 코드들을 배치했습니다.

import { useEffect } from 'react'
import { useRouter } from 'next/router'

export default function UserPage() {
  const router = useRouter()
  const { id } = router.query
  const queryId = Array.isArray(id) ? id[0] : id

  // 문제의 부분 
  // start ------------------------------------------
  if (!queryId) {
    console.error('유효하지 않은 유저 아이디입니다.')
    return
  }

  useEffect(() => {
    if (myInfo && myInfo.id === id) {
      router.push('/mypage')
    }
  }, [myInfo, queryId, router])
  
  const { isLoading, isError, data } = useQuery({
    queryKey: [`userInfo${queryId}`],
    queryFn: () => getUserInfo({ userId: queryId! }),
    enabled: !!queryId,
  })
  // end --------------------------------------------

  // 생략...

}

그러나 다음 사진과 같이 'Error: Rendered more hooks than during the previous render.'이라는 오류가 발생하였습니다.

'Error : Rendered more hooks than during the previous render' 오류창

 


🌵 해결 방법

리액트는 컴포넌트가 일관된 순서로 훅을 호출할 것을 기대합니다.

컴포넌트의 첫 렌더링에서 모든 훅은 특정한 순서에 따라 호출되어야 하며, 이 순서가 매 렌더링마다 동일해야 합니다.

 

위의 문제 상황처럼 return 문이 훅을 호출하기 이전에 위치하면, 첫 렌더링에서는 훅이 호출되지 않았는데

다음 렌더링에서는 훅이 호출되어 순서가 달라지기 때문에 'Error: Rendered more hooks than during the previous render.' 오류가 발생하게 되는 것입니다.

 

이를 해결하기 위해서는 훅이 호출되는 순서를 유지하면서 return 문을 렌더링 부분에 배치해야 합니다.

따라서 if 문으로 queryId를 체크하는 부분을 훅 내부로 배치하여, 컴포넌트가 항상 일관된 순서로 훅을 호출하도록 만들었습니다.

import { useEffect } from 'react'
import { useRouter } from 'next/router'

export default function UserPage() {
  const router = useRouter()
  const { id } = router.query
  const queryId = Array.isArray(id) ? id[0] : id

  // 수정한 코드
  // start ------------------------------------------
  useEffect(() => {
    // if 문을 훅 내부로 재배치 
    if (!queryId) {
      console.error('유효하지 않은 유저 아이디입니다.')
      return
    }

    if (myInfo && myInfo.id === id) {
      router.push('/mypage')
    }
  }, [myInfo, queryId, router])
  
  const { isLoading, isError, data } = useQuery({
    queryKey: [`userInfo${queryId}`],
    queryFn: () => getUserInfo({ userId: queryId! }),
    enabled: !!queryId,
  })
  // end --------------------------------------------

  // 생략...

}

 


읽어주셔서 감사합니다:)