[NEXT JS] Custom hook? 코드 리팩토링

Now, Sophia·2022년 7월 29일
0

TIL_NEXT.JS

목록 보기
4/4
post-thumbnail

Custom Hook?

custom hook은 반복되는 로직을 재사용하는 방법으로 꼭 함수명을 use로 시작하고, 그 안에 함수를 작성한다.
그 안에 useState, useEffect, useReducer, useCallback 등 Hooks를 사용하여 원하는 기능을 구현한다.

기존코드

다른 페이지에서 반복적으로 동일한 코드로 api를 호출하다보니 코드가 길어져 utils라는 폴더에 넣어서 관리했다.
예를 들면, 장바구니 호출하는 api.!
상단 헤더의 컴포넌트 종류에 따라 다 장바구니를 호출했어야 했기 때문에 반복되는 코드가 많았다.

* 함수파일

// 비회원 장바구니 조회
export async function nonMemberCartAPI(checked_flg) {
  const requestOptions = {
    method: "POST",
    headers: {
      "Content-type": "application/json",
      "Access-Control-Allow-Credentials": true,
      Authorization: "",
      specialKey: document.cookie
        .split("identity-key=")[1]
        ?.split(" ")[0]
        .replace(";", ""),
    },
    body: JSON.stringify(checked_flg),
  };

  const res = await fetch(
    `${API.nonMemberCart}?`,
    requestOptions
  );
  const data = await res.json();

  return data;
}

// 회원 장바구니 조회
export async function memberCartAPI(checked_flg) {
  const requestOptions = {
    method: "POST",
    headers: {
      "Content-type": "application/json",
      "Access-Control-Allow-Credentials": true,
      Authorization: document.cookie
        .split("token=")[1]
        ?.split(" ")[0]
        .replace(";", ""),
      specialKey: document.cookie
        .split("identity-key=")[1]
        ?.split(" ")[0]
        .replace(";", ""),
    },
    body: JSON.stringify(checked_flg),
  };

  const res = await fetch(
    `${API.memberCart}`,
    requestOptions
  );
  const data = await res.json();

  return data;
}

* 함수적용하는 파일

import { memberCartAPI, nonMemberCartAPI } from "../utils/function";

const Header = () => {
  const [cart, setCart] = useState([]);
  
   useEffect(() => {
     if ( document.cookie.split("token=")[1]?.split(" ")[0].replace(";", "") !== undefined) {
       memberCartAPI().then((cartData) => setCart(cartData));
     } else {
    nonMemberCartAPI().then((cartData) => setCart(cartData));
     }
  }, [cart]);
  
	return (
    	<>
        <div>
        	{cart.data}
        </div>
        </>
	)
}
export default Header;

처음에는 리팩토링을 위의 코드처럼 적용했다.
모든 페이지에서는 해당 함수만 호출하면 되니까!
나름 코드도 간결해지고, 리팩토링을 이렇게 하는구나 하고 뿌듯했다.
그리고 그냥 반복되는 함수를 호출해서 쓰는거라고 생각을 단순히 했어서 이게 커스텀훅을 쓰는 거라고 생각했다.

근데 찾아보니 커스텀 훅은 그 안에서 데이터를 바꾸기도 하는 등 use로 우선 선언을 해야 한다는 것이다.
그리고 더 간결한 코드로 바꿀 수 있어보였다.
그래서 커스텀훅을 경험할 겸 상기 함수만 커스텀 훅으로 변경해 보았다.!

* useCartHook.js

import { useEffect, useState } from "react";
import API from "../config";

export default function useCartHook(checked_flg) {
  const [data, setData] = useState([]);

  useEffect(() => {
    let Authorization = document.cookie
      .split("token=")[1]
      ?.split(" ")[0]
      .replace(";", "");
// 회원 토큰 할당

    let specialKey = document.cookie
      .split("identity-key=")[1]
      ?.split(" ")[0]
      .replace(";", "");
// 회원이든 비회원이든 모두에게 할당되는 특정 토큰 할당

    let url;
// 회원 장바구니, 비회원 장바구니 호출하는 api가 각각 다르기 때문에 api 주소 변수로 선언

    if (Authorization !== undefined) {
      url = API.memberCart;
    } else {
      url = API.nonMemberCart;
    }
// 로그인하면 생기는 토큰(Authorization) 이 있으면 회원장바구니 api 할당
// 로그인 하지 않은 경우에는 비회원장바구니 api 할당

    fetch(`${url}`, {
      method: "POST",
      headers: {
        "Content-type": "application/json",
        "Access-Control-Allow-Credentials": true,
        Authorization: Authorization,
        specialKey: specialKey,
      },
      body: JSON.stringify(checked_flg),
    })
      .then((res) => res.json())
      .then((cartData) => {
        setData(cartData);
      });
  }, []);
  return data;
}

* Header.js

import useCartHook from "../utils/useCartHook";

const Header = () => {
  const [cart, setCart] = useState([]);
  const useCartData = useCartHook();
  
   useEffect(() => {
    setCart(useCartData);
     }
  }, [useCartData]);
  
	return (
    	<>
        <div>
        	{cart.data}
        </div>
        </>
	)
}
export default Header;

기존에는 api 주소가 달라서 함수가 2개였다.
리팩토링하면서 함수를 하나로 관리할 수 없을까 하다가 변수에 할당된 값에 따라 api 주소가 변경되도록 했다.

상단 헤더 페이지에서 만든 커스텀 훅인 useCartHook을 호출했고, 적용해보니 훨씬 더 간결해진 코드로 바꿀 수 있었다.!

리팩토링 할 때마다 점점 개선되어가는 점이 정말 뿌듯함을 느낀다.
그러나 항상 이게 정말 맞게 리팩토링을 한건지는 의문이 든다.
근데 정확히 커스텀훅을 사용한 것이 맞나...?ㅎㅎ
좀 더 찾아보고 React hooks들도 많이 써보고 해야겠다.

profile
Whatever you want

0개의 댓글