Custom Hooks

Front-end React

커스텀 훅을 만들 때 use 를 붙이는 이유?

커스텀 훅을 만들 때는 함수 안에 다른 use로 시작되는 함수가 들어있다면 use를 붙인다. Building Your Own Hooks – React에서 나오는 것으론 use 함수들에는 일반적인 함수와는 다르게 작동하는 방식이 다르기 때문에 주의를 주기 위해 명시하는 것을 권장한다.

커스텀훅 예제

페이지를 이동할 때마다 onClick..으로 router.push()를 부르는 것을 돕는 훅을 만들기

import {useRouter} from "next/router";

export default function Menu() {
  // Higher Order Function 방식
  const router = useRouter();
  const handleClickMoveToPage = (path: string) => () => {
    void router.push(path);
  };

  return (
    <>
      <button onClick={handleClickMoveToPage("/board")}>게시판으로 이동</button>
      <button onClick={handleClickMoveToPage("/market")}>마켓으로 이동</button>
      <button onClick={handleClickMoveToPage("/mypage")}>마이페이지로 이동</button>
    </>
  );
}

위의 구조를 Custom Hook으로 바꾸면 아래처럼 공용되는 함수를 만들 수 있다. 또한, Recoil을 사용하여 지금까지 지나간 라우트를 저장하는 글로벌 스테이트를 활용할 수도 있는데, 커스텀 훅을 사용하면 반복되는 코드를 줄이고 가독성을 높일 수 있다.

// store/index.ts -> recoil state initializer
import {atom} from "recoil";

export const visitedPageState = atom({
  key: "visitedPageState",
  default: "",
});
// useMoveToPage.tsx
import {visitedPageState} from "@/commons/store";
import {useRouter} from "next/router";
import {useRecoilState} from "recoil";

export function useMoveToPage() {
  const router = useRouter();
  const [visitedPage, setVisitedPage] = useRecoilState(visitedPageState);

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

  return {
    visitedPage,
    handleClickMoveToPage,
  };
}
// index.tsx
import {useMoveToPage} from "@/components/commons/hooks/useMoveToPage";

export default function Menu() {
  // Custom hook 방식
  const {visitedPage, handleClickMoveToPage} = useMoveToPage();

  return (
    <>
      <button onClick={handleClickMoveToPage("/board")}>게시판으로 이동</button>
      <button onClick={handleClickMoveToPage("/market")}>마켓으로 이동</button>
      <button onClick={handleClickMoveToPage("/mypage")}>마이페이지로 이동</button>
    </>
  );
}