[TIL 0417] Custom Hooks

zitto·2023년 4월 15일
0

TIL

목록 보기
52/77
post-thumbnail

✔️ Custom Hooks 이란 ?

이름 그대로 개발자가 스스로 커스텀 한 훅(함수)을 의미한다.


✔️ Custom Hooks 사용시 주의사항

custom hook을 사용하게되면 함수 네이밍에 use를 사용해줘야 한다.
use를 붙이지 않았을 경우 실행은 되지만 의도와는 다르게 작동되거나 훅의 에러 로그를 볼 수 없게 되고 에러 핸들링이 굉장히 어려워질 수 있다.
https://ko.reactjs.org/docs/hooks-custom.html


✔️ useAuth 함수 만들기

  • src/components/commons/hooks/useAuth.tsx
import { useRouter } from 'next/router'
import { useEffect } from 'react'
function useAuth(){
	const router = useRouter()
	// useEffect 훅스를 사용하고 있기 때문에 커스텀 훅스입니다.
	useEffect(()=>{
		if(!localStorage.getItem("accessToken"){
			alert("로그인 후 이용 가능합니다!")
			void router.push("/23-03-login-check")
		}
	},[])
}

custom hook은 컴포넌트가 아닌 함수이기 때문에 return 부분이 JSX가 아님!

  • custom-hooks-use-auth 폴더의 index.tsx
// useAuth를 실행할 페이지
import { useAuth } from "../../../src/components/commons/hooks/useAuth";
export default function CustomHooksUseAuthPage(): JSX.Element {
  // 1. 왜 hoc처럼 어렵게 했나? class컴포넌트는 hooks이 안되므로
  // 2. custom-hooks라고 했는데, 결국 그냥 함수 아닌겨? 함수 맞음~~이름변경도 가능해!
  // 3. custom-hooks와 함수의 차이는 뭔가?
  // 둘다 함수지만 custom-hooks를 구별하는 이유는 해당 함수 안에서 다른 함수를 사용하고 있기 때문임.
  // 구별 기준 : 내부에 다른 hooks를 포함하고 있는가
  useAuth();
  return <div>PROFILE PAGE</div>;
}

해당 페이지가 실행되면, 상단의 useAuth() 먼저 실행된다.

그럼 토큰을 확인 후 토큰이 존재한다면 프로필 페이지가 정상적으로 작동하고, 그렇지 않다면 로그인 후에 이용하도록 경고창을 띄워주도록 유도할 것이다.


✔️ Custom Hooks로 useMoveToPage 만들기

매번 router를 불러오고 코드를 직접 작성해서 페이지 이동하지 않고, custom hooks로 분리해 관리한다.

  • custom-hooks-use-move-to-page 폴더의 index.tsx
// import { useRouter } from "next/router";
import { useMoveToPage } from "../../../src/components/commons/hooks/useMoveToPage";
export default function CustomHooksUseAuthPage(): JSX.Element {
  // const router = useRouter();
  // const onClickMoveToBoard = () => {};
  // const onClickMoveToMarket = () => {};
  // const onClickMoveToMyPage = () => {};
  // const onClickMoveToPage = (path: string) => () => {
  //   void router.push(path);
  // };
  // const result = useMoveToPage();
  // 커스텀 훅으로 분리한 라우터 사용 -> 리턴을 객체로했기때문에 객체로 받아오는 것!!
  const { onClickMoveToPage } = useMoveToPage();
  return (
    <>
      {/* <button onClick={onClickMoveToBoard}>게시판이동</button>
      <button onClick={onClickMoveToMarket}>마켓이동</button>
      <button onClick={onClickMoveToMyPage}>마이페이지이동</button> */}
      <button onClick={onClickMoveToPage("/boards")}>게시판이동</button>
      <button onClick={onClickMoveToPage("/products")}>마켓이동</button>
      <button onClick={onClickMoveToPage("/mypages")}>마이페이지이동</button>
    </>
  );
}

✔️ useMoveToPage() 만들기

  • src/components/commons/hooks/useMoveToPage.tsx
import { useRouter } from "next/router";
import { useRecoilState } from "recoil";
import { visitedPageState } from "../../../commons/stores";
interface IUseMoveToPageReturn {
  visitedPage: string;
  onClickMoveToPage: (path: string) => () => void;
}
export const useMoveToPage = (): IUseMoveToPageReturn => {
  const router = useRouter();
  const [visitedPage, setVisitedPage] = useRecoilState(visitedPageState);
  // path기록시 글로벌스테이트에 저장할 것
  const onClickMoveToPage = (path: string) => () => {
    // localStorage.setItem("visitedPage",path) 로컬스토리지도 가능!
    setVisitedPage(path); //로그인페이지일 때는 set하지 않도록 조건이 추가되야 함.
    void router.push(path);
  };
  return {
    visitedPage,
    onClickMoveToPage,
  };
};

함수의 인자로 라우팅할 주소를 넘겨주면 해당 페이지로 라우팅 된다.

다녀간 페이지들은 RecoilState에 넣어두어 필요한 시기에 적절한 시점에 사용해주면 된다.

또한 리턴은 하나만 해줄 수 있으므로 객체로 묶어 리턴을 해준다.

profile
JUST DO WHATEVER

0개의 댓글