걱정이 너무 많은 기술면접 준비 한번 열심히 해보도록 하자 😂
"Promise 는 단어 그대로 '약속'입니다. "
"프로미스를 사용하면 비동기 메서드에서 마치 동기 메서드처럼 값을 반환할 수 있습니다."
(동기는 '직렬적'으로 작동하는 방식이고 비동기는 '병렬적'으로 작동하는 방식입니다. 즉, 비동기란 특정 코드가 끝날때 까지 코드의 실행을 멈추지 않고 다음 코드를 먼저 실행하는 것을 의미합니다.)
"비동기 연산이 종료된 이후 미래의 어떤 시점에 결과를 제공하겠다는 '약속'입니다."
"Promise 가 미래에 제공하는 결과로는 실패 혹은 완료와 그 결과 값을 나타냅니다."
"Promise 에 처리기를 연결하면 결과값, 실패 사유 등을 처리할 수 있게 됩니다."
"Promise 는 비동기 작업시에 결과를 제공받기위해 필요합니다."
Promise는 class이기 때문에 new 키워드를 통해 Promise 객체를 생성합니다.
또한 Promise는 비동기 처리를 수행할 콜백 함수(executor)를 인수로 전달받는데 이 콜백 함수는 resolve, reject 함수를 인수로 전달받습니다.
코드가 정상적으로 처리가 되었다면 resolve 함수를 호출하고 에러가 발생했을 경우에는 reject 함수를 호출하면 됩니다.
State : 기본 상태는 pending(대기) 입니다. 비동기 처리를 수행할 콜백 함수가 성공적으로 작동했다면 fulfilled(이행)로 변경이 되고, 에러가 발생했다면 rejected(거부)가 됩니다.
Result : 처음은 undefined 입니다. 비동기 처리를 수행할 콜백 함수가 성공적으로 작동하여 resolve(value)가 호출되면 value(값)로, 에러가 발생하여 reject(error)가 호출되면 error로 변합니다.
Then : 작성했던 코드들이 정상적으로 처리가 되었다면 resolve 함수를 호출하고 .then 메서드로 접근할 수 있습니다.
Catch : 작성했던 코드들이 에러가 발생했을 경우에는 reject 함수를 호출하고 .catch 메서드로 접근할 수 있습니다.
Finally : 작성했던 코드들의 정상 처리 여부와 상관없이 .finally 메서드로 접근할 수 있습니다.
"순수함수란, 오직 함수의 입력만 함수의 결과에 영향을 주는 함수입니다."
"순수 함수는 외부의 상태를 변경하지 않으면서 동일한 인자에 대해 항상 똑같은 값을 리턴하는 함수입니다."
( 일반적으로 사이드 이펙트라는 말을 할 때는 '의도하지 않은 결과'를 의미합니다. 본인이 짠 코드가 예상하지 못하는 문제를 발생 시켰을때 )
"따라서, 사이드 이펙트가 없는 예측 가능한 함수입니다."
"메모리에 이미 담긴 데이터를 변경하지 않는다는 뜻입니다."
"메모리에 이미 단긴 데이터가 변경되면 사이드 이펙트가 발생할 수 있기 때문입니다."
"따라서 메모리에 이미 담긴 데이터를 업데이트 하고 싶을 시에는 새로운 변수 혹은 객체를 선언하여 할해당 데이터를 할당하는 것이 불변성에 합당한 방식입니다."
state는 자기자신의 컴포넌트에서 만들어낸 데이터입니다. 컴포넌트에서 관리합니다
"'상태', 즉 컴포넌트 내에서 변할 수 있는 값입니다."
state는 리액트에서 변수 대신 사용하는 데이터 저장공간으로 문자, 숫자, array, object 모두 저장 가능하다.
변수가 아닌 state를 사용하는 이유는 html을 새로고침 없이 자동으로 재렌더링할 수 있기 때문이다.
변경이 자주 일어나거나 중요한 데이터를 주로 저장하고 직접적인 값 변경이 불가능하기 때문에 대체함수를 사용한다.
"일반적으로 컴포넌트의 내부에서 변경 가능한 데이터를 관리해야할 때에 사용 합니다"
"토글, 체크박스, 인풋밸류 등에서 대표적으로 쓰입니다."
"뷰에 렌더링돼야 하는 컴포넌트의 데이터를 저장하는 데 사용합니다"
"컴포넌트에서 동적인 값을 상태(state)라고 부르며, 동적인 데이터를 다룰 때 사용됩니다."
"React 에서 제공되는 useState() Hook 또는 외부 상태관리 라이브러리를 사용하여 관리합니다."
state의 이름과 초기값을 constructor(생성자)에서 설정해 주고, render() 함수에서 this.setState 함수를 통해 state를 변경해 줄 수 있습니다.
setState로 state의 값을 변경한 다음, 다른 특정한 작업을 하고자 할 때에는 setState의 두 번째 파라미터에 콜백 함수(callback function)를 등록하면 됩니다.
"'변하지 않는 값'이면서 '부모 컴포넌트에서 전달 받은 값'입니다."
"어떤 타입의 값도 할당하여 전달할 수 있도록 '객체 형태'입니다."
"그리고 '읽기 전용 객체'로 함수 컴포넌트나 클래스 컴포넌트 모두 컴포넌트의 자체 props를 수정해서는 안 됩니다."
"모든 React 컴포넌트는 자신의 props를 다룰 때 반드시 순수 함수처럼 동작해야 합니다."
"외부로 부터 전달 받은 이미지를 ui에 표기해줍니다."
"데이터, 이벤트 핸들러를 자식 컴포넌트에 전달하는 데 사용합니다"
프로퍼티에 문자열을 전달할 때는 큰따옴표(" ")를, 문자열 외의 값을 전달할 때는 중괄호({ })를 사용 합니다. "
"동일한 컴포넌트를 재사용 할 수 있습니다."
"리액트는 컴포넌트의 key 프로퍼티 값이 변하면 새로운 요소로 인식합니다."
"즉, 리액트는 key 프로퍼티 값을 기준으로 각 컴포넌트들을 인식합니다."
"따라서 컴포넌트의 key 프로퍼티 값을 state 로 주게되면 상태변화를 통해 여러개의 컴포넌트가 있는 것 같은 효과를 줄 수 있습니다."
"대표적으로 Motion UI 에서 key 값을 state 로 주고 Slider 를 구현합니다."
리액트는 컴포넌트의 상태나 속성(prop)이 변할 때마다 render()함수를 호출하는데,
이 때 render()함수는 새로운 리액트 요소 트리를 반환하고 이를 기존의 요소 트리와 비교해 새로운 변경점에 대해서만 재렌더링을 수행합니다.
여기서 기존 요소들 뒤에 새로운 내용을 추가할 경우 새로운 부분에 대해서만 재렌더링 되지만
새로운 요소를 기존요소 앞에 추가할 경우 모든 부분이 재렌더링 됩니다. 바로 이런 상황을 최적화 하기 위해 key 속성을 사용합니다.
각 요소에 key 속성을 부여하면 더 이상 모든 요소를 렌더링하지 않고 추가된 부분만 재렌더링 하는 효율적인 렌더링을 시도합니다.
key값을 인덱스로 설정하면 key를 사용하지 않은 것과 같이 모든 형제 요소가 재렌더링 됩니다. 이는 성능하락이나 예상치 못한 문제를 발생시킵니다.
일반적으로 함수형 컴포넌트 내부에서 발생하는 side effect를 처리할 때 react 모듈에서 제공하는 useEffect함수를 사용합니다.
첫 번째 파라미터로 입력한 함수가 호출되는 시점은 컴포넌트가 첫 렌더링 되는 시점과 두 번째 파라미터로 입력된 dependency array의 각 element의 값이 변경되었을 때 입니다.
dependency array의 각 element의 값이 변경되는지 판단하는 시점은 컴포넌트가 렌더링되는 시점입니다. 컴포넌트가 랜더링 될 때마다 선언해 놓은 useEffect함수가 실행 되고 콜백 함수와 dependancy array가 파라미터로 전달됩니다. 그러면 useEffect함수의 내부 로직에 의해 dependancy array를 캐싱하고 있고 이전 각 element를 반복하면서 dependancy array의 element와 비교(===)한 뒤 다르면 첫 번째 파라미터인 콜백을 호출하는 구조입니다.
즉 "useEffect 는 디펜던시 어레이의 요소에 해당하는 상태가 변경될때 마다 실행됩니다."
"예를들어, 디펜던시 어레이가 inputValue 라는 상태를 요소로 가지고 있다고 했을때, setInputValue 를 통해 inputValue 가 변경될 때마다 useEffect 내부에 있는 함수를 실행시켜줍니다."
"디펜던시 어레이가 비어있는 경우는 해당 컴포넌트 첫 렌더링 시에만 실행됩니다."
"디펜던시 어레이가 아예 없는 경우는 모든 상태가 변경 될때, 렌더링 될때마다 실행됩니다."
어디까지 컴포넌트의 side effect라고 정하는 것은 각자의 몫이지만 useEffect 함수를 만든 의도는 컴포넌트의 상태 (props, state)의 변화에 따라 상태를 이용해 리액트와 관련 없는 부수 작업(side effect, dom 직접변경, api호출 등)를 처리하기 위한 것이기 때문이다.
"SSR 은 Server Side Rendering의 줄임말입니다. 웹 페이지를 브라우저에서 렌더링하는 대신에 서버에서 렌더링합니다."
"CSR 은 Client Side Rendering 을 의미합니다. 일반적으로 CSR은 SSR의 반대로 여겨집니다. SSR이 서버 측에서 페이지를 렌더링한다면, CSR은 클라이언트에서 페이지를 렌더링합니다."
"웹사이트가 그려지는 과정인 '렌더링'을 '어디서' 하느냐의 차이가 있습니다."
CSR의 경우 HTML, CSS와 모든 스크립트들을 한 번에 불러옵니다.
반면 SSR은 필요한 부분의 HTML과 스크립트만 불러오기 때문에 평균적으로 SSR이 더 빠르게됩니다.
첫 페이지를 로딩한 후, 사이트의 다른 곳으로 이동하는 식의 동작을 가정한다고 했을 때,
CSR은 이미 첫 페이지 로딩할 때 나머지 부분을 구성하는 코드를 받아왔기 때문에 상대적으로 빠릅니다.
반면, SSR은 첫 페이지를 로딩한 과정을 다시 실행하게 됨으로 상대적으로 더 느립니다.
"SSR 은 검색 엔진 최적화와 첫 화면 렌더링 속도의 장점이 있습니다."
"CSR 은 상호작용 측면에서 월등한 UX 제공하는 장점이 있습니다."
SSR은 매번 서버에 요청을 하기 때문에 서버 자원을 더 많이 사용합니다.
반면 CSR은 클라이언트에 한번에 요청을 몰아주고 (초기 진입 속도는 느림) 그 후로는 필요한 데이터만 갱신하면 되기 때문에 서버에 부하가 적습니다.
네이버 블로그는 검색엔진 최적화에 유리한 이점이 있기 때문에 SSR 방식입니다. 블로그 같은 경우는 특히 검색엔진에 최대한 노출되는 게 유리하고,
다른 웹사이트에 비해 사용자와 상호작용이 많지 않기 때문에 SSR이 합리적인 선택이 될 수 있겠습니다.
많은 예약 사이트들은 CSR을 사용하고 있습니다. SSR에서는 서버에서 렌더링을 해야 하기 때문에
상호작용(interaction)이 많아질수록 서버에 부담이 많은 반면에, CSR에서는 서버가 클라이언트에 필요한 데이터만 넘겨주기 때문에 부담이 적습니다.
그리고 SPA(Single Page Application)를 기반으로 화면의 일부만 받아온 데이터로 변경해 주기 때문에 빠른 렌더링으로 User Experience(사용자 경험)에 유리합니다.
"따라서 요즘은 상황에 따라 SSR 과 CSR 을 합쳐서 각각의 장점을 취하는 것이 트렌드입니다."
데이터를 읽거나(Read), 검색(Retrieve)할 때에 사용되는 method입니다.
"HTTP 요청인 GET 메서드는 특정 리소스의 데이터를 요청하고 응답으로 오직 데이터를 받기만 합니다."
GET은 불필요한 요청을 제한하기 위해 요청이 캐시될 수 있습니다.
파라미터에 내용이 노출되기 때문에 민감한 데이터를 다룰 때 GET 요청을 사용해서는 안 됩니다.
GET 요청은 브라우저 기록에 남습니다.
GET 요청을 북마크에 추가할 수 있습니다.
GET 요청에는 데이터 길이에 대한 제한이 있습니다.
리소스를 요청할때 사용
서버에게 동일한 요청을 여러 번 전송하더라도 동일한 응답이 돌아옵니다
리소스를 생성/업데이트하기 위해 서버에 데이터를 보내는 데 사용됩니다.
"HTTP 요청인 POST 메서드는 특정 리소스에 엔티티를 제출할 때 사용합니다."
"종종 사이드 이펙트로 부작용을 일으킬 수 있으니 주의하여 사용합니다."
POST는 서버의 상태나 데이터를 변경시킬 때 사용됩니다.
POST 요청은 캐시되지 않습니다.
POST 요청은 브라우저 기록에 남아 있지 않습니다.
POST 요청을 북마크에 추가할 수 없습니다.
POST 요청에는 데이터 길이에 대한 제한이 없습니다.
리소스를 생성할때 사용
서버에게 동일한 요청을 여러 번 전송해도 응답은 항상 다를 수 있습니다.
엔티티(Entity) : 데이터의 집합 (데이터베이스랑 연관)
데이터베이스 : 데이터베이스는 여러 사람이 공유하며 데이터를 관리하고 사용할 목적으로 만들어진 데이터의 저장소입니다.
HTTP messages는 클라이언트와 서버 사이에서 데이터가 교환되는 방식입니다.
"HTTP 메세지는 크게 "요청"과 "응답"으로 나뉩니다."
"요청(request)은 클라이언트가 서버로 전달해서 서버의 액션이 일어나게끔 하는 메시지고, 응답(response)은 요청에 대한 서버의 답변입니다."
"'요청'과 '응답' 각각 Start Line/Status Line 을 시작으로 Header 와 Body 로 이루어져 있습니다."
start line : 클라이언트가 서버에게 보내는 메시지입니다. start line에는 요청이나 응답의 상태를 나타냅니다. 항상 첫 번째 줄에 위치합니다. 응답에서는 status line이라고 부릅니다.
HTTP headers : 요청을 지정하거나, 메시지에 포함된 본문을 설명하는 헤더의 집합입니다.
empty line : 헤더와 본문을 구분하는 빈 줄이 있습니다.
body : HTTP messages 구조의 마지막에 위치합니다. 요청과 관련된 데이터나 응답과 관련된 데이터 또는 문서를 포함합니다. 요청과 응답의 유형에 따라 선택적으로 사용합니다.
이 중 start line과 HTTP headers를 묶어 요청이나 응답의 헤드(head)라고 하고, payload는 body라고 이야기합니다.
브라우저는 기본적으로 내 서버가 아닌 다른 서버에서 받아온 데이터는 차단합니다. 브라우저가 사용자가 방문하는 사이트를 신뢰하지 않기 때문입니다.
기본적으로 브라우저는 토큰이나 쿠키 등과 같이 사용자의 정보와 관련된 데이터를 저장하는데, 만약 해커가 이를 탈취해 얻은 정보를 해커의 서버로 보내버린다면
큰 문제가 발생하기 때문에 등장한 것이 동일 출처 정책(SOP) 입니다
"'동일 출처 정책'은 '같은 출처의 리소스만 공유가 가능한 정책'입니다. 브라우저는 강제적으로 SOP를 기본으로 합니다."
"'출처'란 프로토콜, 호스트, 포트로 이루어져있습니다.'
그리고 이 이 SOP를 풀어주는 역할을 하는 것이 바로 CORS 입니다.
SOP가 동일한 출처간에만 요청과 응답을 허용하는 정책이였다면 CORS는 그와 반대로 서로다른 출처간에도 요청과 응답을 허용하는 정책입니다.
Origin이 달라도 서버에서 CORS옵션을 허용해주면 다른 Origin으로 응답을 보낼 수 있게 됩니다.
"즉, 특정 외부 출처에게 특정 리소스에 접근할 수 있는 권한을 부여해주는 것 입니다."
CORS의 요청방식에는 크게 두 가지 방식이 있습니다.
먼저 다음과 같은 조건을 만족하면, 브라우저는 해당 CORS 요청을 Simple Request로 처리합니다.
HTTP Method가 GET, POST, HEAD 중 하나인 경우
Content-Type 헤더가 다음 중 하나인 경우
application/x-www-form-urlencoded
multipart/form-data
text/plain
CORS-safelisted request-header를 포함하는 경우(Fetch spec)
XMLHttpRequest.upload 에 이벤트 핸들러, 리스너가 등록되지 않은 경우
ReadableStream 객체가 포함되지 않은 경우
Preflight Request는 Simple Request의 조건을 만족하지 못할시 브라우저가 자동으로 생성합니다.
Simple Request와 달리 OPTIONS 메서드를 통해 다른 Origin의 리소스로 HTTP 요청을 미리 보내(preflight) 실제 요청이 전송하기에 안전한지 확인합니다.
브라우저는 안전하다고 판단되면 이를 통해 실제 요청을 보내게 됩니다. Cross-Origin 요청의 경우 유저 데이터에 영향을 줄 수 있기 때문에 이와 같이 미리 전송(preflight)합니다.
"서버의 응답 헤더에 'Access-Cotrol-Allow-Origin' 작성을 통해 접근 권한을 부여해 줄 수 있습니다.
Access-Cotrol-Allow-Origin : "응답 헤더 리스트중 하나입니다. 브라우저가 해당 Origin이 리소스에 접근 가능하도록 허용할 때 사용되는 헤더입니다. "