TIL[24일차]. Hydration, HOC/HOF, 권한분기

남예지·2022년 12월 11일
0

TIL

목록 보기
25/47

Next.js렌더링 원리

access token은
브라우저에서 해당 주소를 입력하고 엔터치는 순간 프론트 서버에 접속해서 HTML/css/js 를 다운받아 브라우저에 그려진다. 로그인을 클릭하면 백앤드에서 실제 로그인을 한 뒤 access token을 받아 브라우저로 가져와 글로벌스테이트에 저장한다. 다시 주소를 입력하면 새로운 HTML/css/js을 받아와 기존게 다 사라지고 access token또한 사라지는 문제가 있다.
그래서 새로고침을 해도 날아가지 않을 브라우저에 저장을 해야하고, 브라우저에 저장할 수 있는 공간들을 브라우저 저장소라고 한다.
실무에서는 refrash token을 사용한다. 하지만 그 전에 우선 정확한 방법을 알아보기 위해 LocalStorage에 저장하는 법을 먼저 배워보자.(LocalStorage는 보안문제가 있다.)

브라우저 저장소의 종류와 특징

  • 쿠키(COOKIE) : 영구 저장이 가능하며, 만료시간을 지정 할 수 있습니다.
  • localStorage : 영구 저장이 가능합니다. ⇒ 우리가 임시로 사용할 저장소 입니다.
  • sessionStorage : 브라우저 종료시 사라집니다.

localStorage 사용방법

  • 저장할 때 : **localstorage.setItem(”key” , ”value”)**
  • 꺼내올 때 : localstorage.getItem(”key”)

localStorage에는 객체는 못넣기 때문에 텍스트로 넣어주어야한다.
간단히 객체를 바꿔보면
텍스트로 바꾸기 : JSON.stringify(profile)
다시 객체로 바꾸기 : JSON.parse('{"name":"철수"}')

변수는 자바스크립트를 이용해 넣는거지만 로컬스토리지는 브라우저에 저장하기 때문에 새로고침해도 안나간다.

그런데 새로고침하고 보니 localstorage is not defined라는 에러가 떴다. RequestHeaders에 headers가 비어있어 accessToken이 안받아와진 것이다.
이 부분은 next.js의 작동방식을 이해해야한다.

next.js의 렌더링 방식

브라우저에다 로컬호스트 ~~ 라고 입력하고 엔터를 치면 프론트 서버에 접속해
HTML/css/js를 받아오고 백앤드로 API요청을 받아오는데 이 사이에는 한 단계가 더 있다. 프론트엔드 서버에서 나가기전에 가상으로 한번 그려본 뒤 내보내는 단계인데 이를 가상으로 그린다고 해서 pre-rendering이라 한다. pre-rendering된 화면을 가지고 브라우저에 가져다준다. 브라우저에서 다시 한번 그리고 프리렌더링과 브라우저에 입력된 두개를 비교해서 업데이트를 시켜주는걸 Hydration이라고 한다.
둘의 차이점을 비교하는 걸 diffing이라고 한다.
pre-rendering => diffing => Hydration
순서는 프리렌더링하고 디핑 후 하이드롭션을 한다.

그런데 pre-rendering은 브라우저가 가지고 있는 LocalStorage나 alert등은 없다. 그래서 먼저 화면을 그려보다가 발생하는 오류이다.


alert가 없다고 오류가 났다.

실제로 두 번 그려지는지 확인해보자

if (process.browser) {
    console.log("지금은 브라우저!!!");
  } else {
    console.log(
      "지금은 프론트엔드 서버!!!(즉 yarn dev로 실행시킨 프로그램 내부)"
    );

이 때 터미널 창에는 프론트엔드 서버!! 가 뜨고 브라우저 콘솔창에는 지금은 브라우저!! 라고 두 창에 다르게 뜨는걸 보면 next.js는 프론트서버와 브라우저에서 총 2번 그려지는걸 알 수 있다.
프론트 서버는 함수까지는 그리지 않는다. 그래서 함수 안쪽에 로컬스토리지는 문제가 없었던 것이다.
그래서 문제 해결을 위한 방법 3가지를 알아보면
1. process.browser방법
2.
3.
이 있다
// 1. 프리렌더링 예제 - process.browser 방법
if (process.browser) {
window.alert("안녕하세요!")
console.log("지금은 브라우저!!!");
const result = localStorage.getItem("accessToken")?? ""
setAccessToken(result);
} else {
console.log(
"지금은 프론트엔드 서버!!!(즉 yarn dev로 실행시킨 프로그램 내부)"
);
}
이렇게 하면 무한렌더링 걸려서 별로 좋은 방법이 아니다.

이를 해결하기 위해서는 useEffect를 사용해 렌더링 이후에 실행되도록 하겠습니다.

권한분기

로그인 인증 이후에는 로그인 상황에 따른 권한 분기를 하게 되는데 예를 들어 로그인을 한 사람과 로그인을 하지 않은 사람, 운영자로 로그인한 사람, 판매자로 로그인한 사람, 거래처사장님으로 로그인한 사람 등 다양하게 권한을 분리한다.

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

useEffect로 권한이 없다면 로그인창으로 보내버리기

커스텀 hook을 만들어 쓰거나
클래스 HOC를 하거나

요즘은 커스텀 훅을 많이 쓰지만 클래스 HOC를 쓰는 회사가 아직 많기 때문에 HOC로 한번 적용해보고 커스텀훅으로 바꿔보자.

이걸 하려면 사전 지식으로 클로져를 알아야한다.

Closure 클로저 함수

클로저 전에 우선 스택과 큐라는 데이터 구조를 알아보자.

데이터 구조

stack은 출입구가 하나이기에 나중에 들어간 함수가 가장 먼저 나오는 lastInFirstOut 구조이다. (LIFO 구조)
queue는 출입구가 나눠진 파이프 형태로 가장 먼저 입력된 함수가 가장 먼저 빠져나가는 FirstInFirstOut 구조이다. (FIFO 구조)

스코프체인

스코프는 로컬에 없으면 클로저로 가고 클로저에 없으면 글로벌로 간다. 이렇게 해당 스코프에 없으면 상위 스코프에 있나 스코프를 찾아 올라가는 과정을 스코프 체인이라고 한다.

클로저
클로저라고 함은 상위 함수와, 해당함수(여기서는 bbb함수)가 선언된 스코프 즉 상위함수를 둘러싼 환경
함수 안에 함수안에 함수가 있다면 바깥 함수 2개는 클로저 함수안에 있다.

HOC / HOf

함수를 리턴하는 함수 HOF

function aaa() {
  const apple = 10;

  return function bbb() {
    const banana = 20;

    console.log(banana);
    console.log(apple);
  };
}

aaa()();

(aaa())()
aaa를 실행한 결과값을 다시 실행한다.
이러면 bbb를 실행한 것과 같다.
aaa()()로 줄여 사용이 가능하다.
aaa가 실행되고 bbb가 실행된다.
aaa를 bbb보다 먼저 실행되기 때문에 Higher order Function(먼저 실행되는 함수)이라고 하며 HOF라고 한다. 여기서는 aaa가 HOF이다.

이는 파라미터를 사용해 간결하게 할 수 있다.

// 함수 선언식
function aaa(apple){

	return function bbb(banana){
		console.log(banana)
		console.log(apple)
	}
}

aaa(2)(3)

// 실행 결과
// 2 => aaa에 넣은 인자값
// 3 => bbb에 넣은 인자값

bbb에는 apple이 없지만 클로저에 aaa가 있으므로 콘솔에 //2 //3일 잘 찍히는 걸 확인할 수 있다.
이걸 화살표 함수로 바꿀수도 있다.

// 화살표 함수로 변경
const aaa = (apple)=>{
	return (banana)=>{
				console.log(apple)
				console.log(banana)
		}
}

aaa(2)(3)

이렇게 바꾼 코드에서 중괄호와 리턴 사이에 아무것도 없다면 중괄호를 생략해서 적을 수 있다.

// 중괄호 생략
const aaa = (apple)=>(banana)=>{
				console.log(apple)
				console.log(banana)
}

aaa(2)(3)

HOC

HOC는 상위에 있는 컴포넌트로 다른 컴포넌트보다 먼저 실행되는 컴포넌트
hoc는 hof와 같지만 함수와 컴포넌트라는 차이가 있다.

컴포넌트는 꺽쇠가 있는!! 그 외는 함수이다.


HOC 를 로그인 검증에 응용하기
다른 컴포넌트보다 먼저 실행되게 하기 위해 위에서 배운 함수를 리턴하는 함수를 활용하면 된다.

profile
총총

0개의 댓글