Day 23) 1. Next.js 렌더링에 이런 원리가 있다니!=> Deiffing / Hydration 2. 자바스크립트에 이런것이?! => Closure 3. 잠깐! 이것 먼저 실행해줘! => HOC / HOF

송인호·2022년 6월 9일
1

dailyStudy

목록 보기
22/35

1교시 Next.js 렌더링 원리

Token 은 변수에 담아줬기 때문에 새로고침을 하면 사라지는 것이다
refreshToken을 배우면 그걸 이용하지만 배우기 전까지 임시로 localStorage를 이용해 Token을 담아주겠다.
localStorage 는 보안상의 문제가 있어 권장하지 않는 방법이다.

새로고침을 하면 프론트에서 html,css,js부터 다시 받아온다.(초기화)
그렇기 때문에 state에 저장한 accessToken은 사라지게 된다.

사라지지 않게 하려면 html,css,js와 관련이 없는곳에 저장을 해야한다.

localStorage, sessionStorage, cookie등이 있다.

  • localStorage = 브라우저 껐다 켜도 남아있음.
  • sessionStorage = 브라우저 껐다 키면 사라짐
  • cookie = 브라우저 껐다 켜도 남아있음

cookie = 백엔드 연동 가능 ( API 요청할 때 쿠키를 같이 첨부하여 보낼 수 있음, 데이터를 추가해 받을 수 있음 )

accessToken 경로

  1. accessToken을 global RecoilState 에 담아준다.
  2. headers에 accessToken을 받아서 넣어준다.
  3. router를 이용해 페이지를 넘겨준다.
  4. fetch를 받아 토큰을 이용해 로그인한다.

accessToken을 localStorage에 담아주었다.
에러가 생긴다.

다시 원상복구 한뒤 한곳에서 localStorage에 등록하고 가져오면 localStorage에 저장이 된다.

하지만 왜 ApolloSetting에 서는 localstorage에 accessToken을 못받아 오는 것일까?

Next_JS 과정

이문제로 인해 발생하는 에러가 많이 있다.

  1. 브라우저에 들어가면 가장 기초적인 밑그림을 프론트엔드 서버에서 미리 그려본다.( 프리 렌더링 )
  2. 그 후 html,css,js 를 브라우저에 넘겨준다.
  3. 브라우저에서 다시 한번 그림을 그리게 되고 서버에서 그린 내용과 과정을 비교를 한다. ( diffing )
  4. 변경된 부분이 있으면 최종적으로 브라우저에 반영을 한다. ( hydration ) ex) onClick, onChange, useEffect....~

결론

이렇기 때문에 서버에서 프리렌더링할 때 localStorage가 없다라는 에러메시지가 나온 것 이다.

서버에서 프리렌더링을 하고 브라우저에서 그려지는지
확인은 터미널 창에서 하면된다.

이렇게 프론트엔드 서버에서도 렌더링이 된다는 것을 확인 할 수 있다.
그래서 브라우저에서는 localStorage가 있지만
서버에서는 localStorage가 없다.

방법은 3가지가 있다.
useEffect를 이용하여 사용하겠다.
이렇게 하게 되면 새로고침을 하더라고 accessToken을 유지할 수 있다.

2교시 Closure

권한분기

사장님 사이트, 관리자 사이트, 사용자 사이트 등 사이트를 나눠줄 수 있다.

주소도 각자 다르다.
웹 서비스를 만든다는 것은 보여지는 것 보다 많은 서비스가 유기적으로 이루어져야한다.


d

aaa 함수를 실행하게 되면 aaa만 실행이 되고 return 값으로 bbb함수가 나온다.


이렇게 하면 aaa함수와 bbb함수를 모두 실행시킬 수 있다.

banana는 bbb함수 안에서만 사용할 수 있지만
apple은 bbb함수에 없으면 밖에있는 aaa함수를 참조하여 가져올 수 있다.


bbb 함수 {} 를 로컬스코프
밖에있는 aaa함수 {}를 클로저스코프
로컬스코프 안에 없어서 밖에 클로저스코프에서 값을 받아오는 것을 스코프체이닝이라 불린다.

closure 실습

결과가 잘 나온다.

소스에서 클릭하여 브레이크를 걸어 줄 수 있다.
브레이크포인트를 걸어둔후 새로고침을 하면 그 포인트에서 멈추게 된다. 이것을 디버깅이라 한다.대부분은 콘솔을 찍긴함.

이렇게 해도 가능.

클로저를 이용할 때 그 안에 있는 함수가 끝나야지 다음 함수도 끝낼 수 있다. 그래서 무작위적으로 사용하는 것은 좋지않다.
쓰는데에는 굉장히 효율적이다. 많이 사용


로컬스코프 함수이름은 중요하지 않다

3교시 HOC

useEffect를 이용하여 권한분기 설정해주기는 간단하게 적용할 수 있다.
하지만 필요한 모든 페이지 마다 따라 붙여야 한다.
그렇기 때문에 수정할 때 모두 다 바꿔줘야하는 어려움이 생긴다.

그래서 로그인확인을 적용해주는 공통 컴포넌트를 만들고, 원하는 페이지가 실행되기 전에 먼저 실행하게끔 하면 문제를 해결 할 수 있다.

HOC

즉, 그 페이지가 실행되기 전에 로그인확인을 먼저 실행이 되게끔 하는 컴포넌트를 Higher Order Component( HOC ) 라 한다.

1번과 3번 사이에 useEffect함수를 끼어 넣을려면 어떻게 해야하나...

실행 결과는 먼저 실행 컴포넌트가 있든 없든 실행이 된다.
2번을 넣어줌으로서 props하나 건드리지 않고 단지 먼저 실행 시킬 수 있다.
즉, 나머지는 다 동일하지만 중간에 로직을 추가하여 먼저 실행되게 할 수 있다.( 로직에 useEffect를 추가하면 문제가 해결 된다. )

결론

HOC 컴포넌트를 만들고 로그인확인 페이지에 import하여 감싸준다.
그리고 1번에서 임의의 이름으로 받아준다.


return 부분에 빨간줄이 나오는데 eslint 꺼줘도 상관없다.

결론적으로 아까와 같이 본다면

이렇게 된다.

이제 withAuth만 import하면 로그인 권한분리가 가능해진다.

함수형 컴포넌트로 하게 되면 커스텀훅을 통해 더 쉽게 이용할 수 있을 것이다.

요약

오늘의 로그인 관련 내용은 임시로 적용시켜 줄 수 있는 내용입니다!

지금까지 배운 로그인 프로세스로는 브라우저를 새로고침하거나 페이지를 이동했을 경우 유지가 안됐었죠? 이는 우리가 accessToken을 Browser에 저장시켰기 때문에 화면이 새로 그려지며 초기화 되었기 떄문입니다.

이를 해결하기위해 우리는 브라우저 저장소를 사용할 수 있었죠? 브라우저 저장소에는 3가지가 있었습니다.

Cookie, localStorage, sessionStorage 기억나시나요? 그 중 보안상 문제가 좋지 않지만 원활한 개발을 위해 임시로 localStorage에 저장시켰습니다. localStorage.setItem(“key”,value)과 .getItem(“key”,value)을 활용해 손쉽게 넣어주고 불러줄 수 있었죠?! localStorage는 새로고침 이후에도 사라지지 않는다는 특징이 있었습니다! 즉, 우리가 새로고침한 이후에도 localStorage에 저장 시켜 놓은 accessToken을 setAccessToken을 사용해 집어 넣어주면 만료시간까지 유지가 되겠죠?

여기서 Next.js의 렌더링과 관련된 중요한 포인트가 있었습니다.
Browser에서 요청이 오면 frontend서버에서 미려 그려본 후(Pre-rendering) Browser에 그려준 뒤, 비교(diffing)하고 변경사항을 적용(hydration)해준다고 했습니다. 따라서 frontend 서버에서 그려줄때는 Browser저장소인 localStorage가 없었죠? 따라서 우리는 process.browser 조건이나 typeof window !== ‘undefined’을 주어 실행되는 곳이 Browser일 경우에만 localStorage에 접근하도록 했습니다!

또한 useEffect를 활용하여 화면을 한번 그려준 후 실행시켜주어 해결 할 수도 있었는데, 위 의 3가지 조건 중 우리는 가장 안정적 방식인 useEffect를 사용해주었습니다!

권한 분기의 큰 그림으로는 프론트엔드가 최소 2개 이상으로 분리되었죠!
사용자들이 접속하는 사용자 프론트엔드 서버, 뒤에서 관리자들이 접속하는 관리자 프론트엔드 서버, 더 많게는 판매자용, 구매자용, 중개자용 등등 여러 관리자서버가 존재합니다.

우리는 단지 사용자이기 때문에 매일 사용하는 네이버 홈페이지가 하나밖에 없는줄 알고 있었죠! 하지만 우리가 여태 몰랐던 네이버 관리자 프론트엔드 서버가 존재합니다. 여기에는 네이버 가입자 명단 등등을 게시판 형태로 볼 수 있도록 페이지네이션이 되어있겠죠!

이런 큰 그림의 권한 분기도 있지만, 오늘 배웠던 부분은 사용자 서버 안에서의 로그인한 유저 / 로그인안한 유저를 구분하는 권한 분기였어요!
이 방법으로는 useEffect에서 accessToken이 없으면 /login 화면으로 페이지를 이동시켜 줬습니다.

하지만, 문제가 있었죠! 로그인 권한이 필요한 모든 페이지에 위 로직을 입력해 주어야 한다는 것이었어요!
그래서 우리가 사용한 것이 HOC(Higher Order Component) 였습니다!
HOC(HighOrderComponent)를 알아보기 위해 HOF(HighOrderFunction)도 알아봤죠! 이 개념을 위해 우리는 클로저(closure)의 개념에 대해 배웠는데 그 안에서 우리는 스택구조 대해서 먼저 알아봤어요, 스택구조는 FIrst-in/Last-out(Last-in/First-out) 구조로 즉, 먼저 실행되는 순서대로 쌓이는 구조였습니다! 이 안에서 스코프(범위)의 개념도 알게됬습니다. 스코프 체인! Local->Closure(가장 가까운 외부 함수)->Global 순으로 찾아 간다고 했습니다! 다시말해, 클로저는 외부 함수에 접근할 수 있는 내부 함수를 말합니다!

HOC와 HOF는 Componenet와 Function의 차이였죠!
다시말해, JSX(React의 HTML)를 return 하면 Component, 그렇지 않으면 Function 이었습니다.

HOF 사용 장점은, 기존처럼 event.target.id 라고 직접 입력하지 않아 코드가 짧아진다는 점이었어요!
기존에 material-ui, ant-design 등의 컴포넌트를 이용하면 id값이 날라가는 현상이 있었죠!

또한, id는 전체 태그에서 고유해야하기 때문에, id가 남용되면 대규모 서비스에서 예기치 못한 상황이 발생할 수 있었습니다.
HOF를 사용하면 이러한 점들을 사전에 방지해 줄 수 있고, 사용이 더욱 쉬었어요!

HOC란 특정 컴포넌트를 실행하기 전에 상위 컴포넌트를 먼저 실행시켜 주는 것이었죠!
이렇게 되면 HOC를 하나 만들어 놓고, 로그인이 필요한 컴포넌트 앞에 HOC만 붙여주면 간단하게 권한처리가 끝났습니다!

또한, HOC는 다른 컴포넌트와 함께 실행되므로 with라는 이름을 앞에 붙여줬습니다.
withAuth, withApollo 등이 그 예입니다.
이렇게 우리를 편하게 해주는 HOC와 HOF !!
이게 가능했던 이유는 Javascript의 클로저 덕분이었습니다!

알고리즘

나누기

(A + B) % c === (( A % C ) + ( B + C )) % C

피보나치 수열

메서드 사용

profile
프론트엔드 개발자

0개의 댓글