인프런 커뮤니티 질문&답변

joka님의 프로필 이미지
joka

작성한 질문수

[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스

24-05-custom-hooks-use-auth / custom-hooks-use-move-to-page

useMoveToPage 안에 onClickMoveToPage 함수를 따로 만드는 이유

작성

·

124

0

ex1) useMyMoveToPage1.tsx

import { useRouter } from "next/router";

export const useMyMoveToPage1 = (path: string) => () => {
  const router = useRouter();  // error

  void router.push(path);
};

ex2) useMyMoveToPage2.tsx, 강의내용

import { useRouter } from "next/router";

interface IUseMyMoveToPage2Return {
  onClickMoveToPage: (path: string) => () => void
}

export const useMyMoveToPage2 = (): IUseMyMoveToPage2Return => {
  const router = useRouter();

  const onClickMoveToPage = (path: string) => () => {
    void router.push(path);
  };

  return { onClickMoveToPage };
};

ex3) /test/index.tsx

import { useMyMoveToPage1 } from "../../src/components/commons/hooks/useMyMoveToPage1";
import { useMyMoveToPage2 } from "../../src/components/commons/hooks/useMyMoveToPage2";

export default function TestPage() {
  const { onClickMoveToPage } = useMyMoveToPage2();

  return (
    <>
      <button onClick={useMyMoveToPage1("/test/01")}>
        useMyMoveToPage: Move To Test01 Page
      </button>
      <button onClick={onClickMoveToPage("/test/01")}>
        useMyMoveToPage2: Move To Test01 Page
      </button>
    </>
  );
}

[useMyMoveToPage1 error 내용]

화면 캡처 2024-03-29 183937.png

useMoveToPage 만들기를 실습하다가 더 짧게 리팩토링할 수 있을 것 같다는 생각에 맨위에 ex1 처럼 해봤는데 const router = useRouter() 부분에 문제가 있다고 하더라구요. 에러 내용을 번역해서 봐도 "잘못된 hook 호출이고 함수 컴포넌트 내부에서만 호출될 수 있다"라고 하는데 무슨 말인지도 사실 잘 모르겠습니다.. 강의내용처럼 useRouter를 밖에 두고 onClickMoveToPage라는 hof 함수를 따로 만들어 return 해줘야 문제가 없다는 것은 알겠지만 음... 이해가 되지 않아서 더 자세한 원리와 error가 나는 이유에 대해서 알려주시면 감사드리겠습니다. 잘 알려주시는 것에 비해 제 부족한 학습능력이 살짝 부끄럽네요 ㅠㅠ

답변 1

1

안녕하세요, 인프런 AI 인턴입니다.

님의 질문에 대한 답변입니다.

당신이 겪고 있는 에러는 React Hooks의 사용 규칙에 위배되기 때문에 발생합니다. Hooks는 반드시 React 함수 컴포넌트의 최상위에서 직접적으로 호출되어야 합니다. 즉, 다른 함수, 조건문, 반복문, 중첩 함수 내부에서 Hooks를 호출하면 안 됩니다.

ex1 예제에서 useMyMoveToPage1 함수는 path를 인자로 받고, 바로 useRouter Hook을 호출하는 함수를 반환합니다. 여기서 useRouter가 컴포넌트 최상위가 아닌 반환된 함수 내부에서 호출되기 때문에 에러가 발생합니다. 이 코드는 Hooks의 사용 규칙에 위배됩니다. React는 이러한 호출을 감지하고 “잘못된 hook 호출”이라는 에러를 발생시킵니다.

반면, ex2 예제에서는 useMyMoveToPage2 함수 내부에서 useRouter를 사용하여 onClickMoveToPage 함수를 만들고 이를 반환합니다. 여기서 useRouter Hook은 직접적으로 useMyMoveToPage2 함수 내부에서 호출되고 있으며, 이는 Hooks의 사용 규칙을 준수합니다. 따라서 이러한 구조는 에러를 발생시키지 않고 정상적으로 동작합니다.

이런 차이 때문에 ex1 방식이 에러를 발생시키는 반면, ex2 방식은 에러 없이 정상적으로 동작하는 것입니다. Hooks를 사용할 때는 이러한 규칙을 꼭 지켜야 합니다.

잘못된 Hook 호출에 대한 자세한 내용과 해결 방법은 React 공식 문서를 참조하시면 도움이 될 것입니다.
React 공식 문서 - 잘못된 Hook 호출

이해가 되지 않는 부분이 있다면 언제든지 질문해 주세요. 학습하는 과정에서 이해가 안 되는 부분이 있다면 당연히 질문을 통해 해결하는 것이 좋습니다. 부족함을 느끼기보다는 꾸준히 학습해 나가는 과정에서 발전을 이룰 수 있습니다. 계속해서 열심히 학습해 주세요!

joka님의 프로필 이미지
joka

작성한 질문수

질문하기