20220215_TIL : 권한 처리를 위한 HOC / HOF

권지현·2022년 2월 15일
0
post-thumbnail

로그인 절차를 처리하는 과정에서 정보를 입력한 사용자와 DB에 저장된 사용자가 일치한다는 것을 의미하는 토큰을 받아오는 것까지 배웠다.

하지만 이 벡엔드로부터 받아온 토큰은 브라우저를 새로고침했을 때 정보가 초기화된다는 문제가 있었다. 이 문제를 방지하기 위해 브라우저 저장소에 토큰을 객체 형태로 저장해주는 방법을 배웠다.

브라우저 저장소는 크게 Cookie, localStorage, sessionStorage 이렇게 3가지 나뉘고 개발을 위해 localStorage 에 임시 저장시켜주는 방법을 이용했다.

//setItem("key",value) 값으로 localStorage에 저장
if (setAccessToken) {
  setAccessToken(accessToken || "");
  localStorage.setItem("accessToken", accessToken || "");
}

코드를 단순히 이렇게 짜게 되면 페이지가 렌더될 때 오류가 발생한다.

💡 Next.js Rendering

프론트엔드 서버에서 브라우저로 전송하기 전 preRendering -> html,css,js 전송 -> 최종 사용자가 확인하기까지 diffing (프론트엔드 서버와 브라우저 렌더링 결과물 비교 ) -> hydration (브라우저에서 렌더링 최종 결과물 렌더링)

preRendering 과정에서는 브라우저가 아니기 때문에 localStorage에 대한 정보를 가져올 수 없기 때문에 localStorage.getItem 에 대한 코드를 읽지 못해서 생기는 오류이다.

이 문제를 해결하기 위해 브라우저에서 실행될 수 있도록 조건을 설정해주어야한다.

// 1. 브라우저에서 실행
// if(typeof window !== "undefined") 혹은
  if(process.browser){
    if (localStorage.getItem("accessToken")) {
      setAccessToken(localStorage.getItem("accessToken") || "");
   	}
}

// 2. useEffect로 렌더된 후에 실행하도록 만들어줌
useEffect(() => {
  if (!localStorage.getItem("accessToken")) {
    alert("로그인을 먼저 해주세요!");
  }
}, []);

이 코드를 모든 페이지에 적어주기보다 하나의 컴포넌트에 적용시키고 그 컴포넌트를 로그인이 필요한 페이지에 적용시키기 위해 사용하는 것이 HOC

💡 HOC / HOF

Closure - 함수가 선언된 환경의 스코프를 기억하여 함수가 스코프 밖에서 실행될 때에도 이 스코프에 접근할 수 있게 하는 기술 쉽게 말해 내부 함수에서 외부 함수의 지역변수에 접근하는 것

클로저를 활용한 방식 두 가지 - HOC / HOF

HOC - Higher Order Component
로그인 절차를 거치거나 관리자 혹은 회원만 이용할 수 있는 페이지를 만든다고 가정할 페이지가 로드되기 전 로그인을 통해 관련 페이지로 이동시켜주도록 중간 컴포넌트로 활용된다.

// withAuth HOC
export const withAuth = (Component) => (props) => {
  const router = useRouter();

  useEffect(() => {
   // useEffect로 렌더될때 한번만 실행
    if (!localStorage.getItem("accessToken")) {
      alert("로그인을 먼저 해주세요!");
      router.push("/23-04-login-check");
    }
  }, []);

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

HOF - Higher Order Function

export default function HofPage() {
  const onClickChid = (el: string) => (event: MouseEvent<HTMLDivElement>) => {
    console.log(el);
  };
  return (
    <div>
      <h1> HOF연습페이지입니다 </h1>
      {["철수", "영희", "훈이"].map((el, index) => (
        <div key={el} onClick={onClickChid(el)}>
          {el}
        </div>
      ))}
    </div>
  );
}

HOC / HOF 차이 ?
Component , function 의 차이 => JSX(html) return 여부

profile
FE 개발자 성장 기록 👩🏻‍💻

0개의 댓글