HOC: 먼저 실행하는 컴포넌트 만들기

2023. 7. 14. 07:26Next.js

728x90
반응형

HOC가 가능해지는 원리부터 알아보자!

 

컴포넌트를 가져올 때 사용하는 일반적인 방법이다.

(Aaa 컴포넌트에서 Bbb 컴포넌트를 불러오고 있다.)

 

 

이때, Bbb 컴포넌트를 불러오는 방식을 함수를 호출하는 형태로 변경할 수 있다.

 

 

여기에 컴포넌트를 하나 더 추가해보자.

추가하는 컴포넌트는 Aaa가 Bbb를 불러올 때 그 사이에 실행시킬 것이다.

 

  • `먼저 실행 컴포넌트`를 보면, 함수 안에서 함수(Component)를 리턴하면서
    리턴하는 함수의 props를 리턴되는 컴포넌트에 전달해주고 있다.
  • 이를 활용하면
    Aaa를 실행시키면 Bbb 컴포넌트에 props는 그대로 전달하고, 먼저 실행 컴포넌트에서 필요한 로직들을 먼저 실행시킬 수 있게 된다.

이렇게 중간에 추가한 `먼저 실행 컴포넌트`를 Higher Order Component라고 부른다.

 

활용: 로그인 여부 확인이 필요한 페이지에 HOC를 추가해서 accessToken 등을 체크하여 권한을 분기하는 데 활용할 수 있다.

 


더 간단하게 바꿔보자

Aaa 컴포넌트

  • Bbb를 HOC로 감싸서 합쳐서 export한 것을 Aaa에서 import해서 쓰고 있다.
    👉🏻 HOC(Bbb)가 export default이기 때문에, Aaa에서 Bbb로만 적어도 HOC(Bbb)가 실행된다.

 

먼저 실행 컴포넌트

  • 👉🏻 중괄호와 리턴 사이에 아무것도 없으므로, 화살표 함수로 바꾸어 코드를 줄일 수 있다.

 


 

HOC 만들기

HOC의 함수명은 with~로 짓는 게 국룰🌟

 

1. withAuth 컴포넌트를 만든다.

 

// prettier-ignore
export const withAuth = (Component : ComponentType) => <P extends {}>(props:P) => {
  const router = useRouter();

  /* 권한 분기 */
  useEffect(() => {
    if (!localStorage.getItem("accessToken")) {
      alert("로그인 후 이용이 가능합니다.");
      router.push("/23-04-login-check");
    }
  }, []);

  return <Component {...props} /> ;
}

 

2. HOC을 먼저 실행시킬 컴포넌트를 HOC으로 감싸서 내보낸다.

로그인이 필요한 페이지를 1에서 만든 withAuth로 감싸서 export default하면 해당 페이지가 실행되기 전에 withAuth가 먼저 실행된다.

 

요로케 👉🏻 export default withAuth(LoginSuccessPage);

import { gql, useQuery } from "@apollo/client";
import { withAuth } from "../../src/components/commons/hocs/withAuth";

const FETCH_USER_LOGGED_IN = gql`
  query fetchUserLoggedIn {
    fetchUserLoggedIn {
      email
      name
    }
  }
`;

function LoginSuccessPage() {
const { data } = useQuery(FETCH_USER_LOGGED_IN);

  return <div>{data?.fetchUserLoggedIn.name}님 환영합니다.</div>;
}

export default withAuth(LoginSuccessPage);
// withAuth가 먼저 실행된다.
// HOC의 매개변수인 Component에 LoginSuccessPage가 들어간다.
728x90
반응형