Rendered more hooks than during the previous render.

Sinf·2022년 9월 13일
8

고민의 흔적

목록 보기
37/38
post-thumbnail

씬프로드에서 유저 페이지의 코드를 작성하던 중 만난 에러.

해당 로직의 흐름은

  1. 전역 상태에서 유저의 정보를 가져온다.
  2. 유저 정보가 없다면 로딩 컴포넌트를 리턴한다.
  3. 유저 정보에 따라 이메일, 이름을 하나의 상태로 관리한다.
  4. 유저 정보 페이지를 리턴한다.

리액트에서 컴포넌트 리턴

유저의 정보가 있을 때, 상태를 호출하고 컴포넌트를 리턴하도록 작성하기 위해 중간에 조건문을 사용해 유저 정보가 없으면 로딩 컴포넌트를 호출하도록 했다.

export function component1() {
  const { user } = store();
  	
  if (!user) {
    return <Loading />;
  }
  
  const [email, setEmail] = useState<string>(user.email)
  
  return <div>{email}</div>;
}

하지만 여기서 해당 에러가 발생한 것.

컴포넌트 리턴 이후에 useState가 발견되어 해당 에러가 발생했다.

리액트에서 컴포넌트가 호출될 때,
해당 컴포넌트에서 사용되는 상태들을 확인하고,
리턴을 만나면 페이지를 렌더링한다.

하지만 위와 같이 짠 로직은
이미 렌더를 하는데 페이지에서 사용될 수 있는
상태를 선언하게 된 것이다.

해결

일단, 먼저 리액트에서는 useState와 같은 hooks를 리턴문 앞에 모두 선언되도록 한다.

하지만, 현재 상황은 유저 정보가 있는지 확인할 필요가 있다.

export function component2({ user }) {
  const [email, setEmail] = useState<string>(user.email);
  
  return <div>{email}</div>;
}

export function component1() {
  const { user } = store();
  	
  if (!user) {
    return <Loading />;
  }
  
  return <Component2 user={user} />;
}

그래서 유저 정보를 보여주는 컴포넌트를 하나 생성하여
상태를 관리하고 조건문과 상태 관리가 역순이 되지 않도록 했다.

profile
주니어 개발자입니다. 🚀

2개의 댓글

comment-user-thumbnail
2023년 10월 18일

정말루다가 감사합니다.. 에러 해결하는데 많은 도움이 되었습니다.. 복 많이 받으세요

답글 달기
comment-user-thumbnail
2024년 3월 27일

원인에 대해서 알게되었네요! 감사합니다.

답글 달기