프론트 개발자로서 중요하다 생각하는 것?
- 사용자 경험에 대한 고민이 중요하다 생각함. 사용자가 서비스를 정상적으로 사용할 수 있게끔 오류 없는 비지니스 로직을 만드는 것 부터 시작해서 크게는 서비스 전반에 발생할 수 있는 이슈를 선제적으로 파악하기 위한 이슈 트레커를 추가하는 것까지 사용자 경험에 대한 고민의 일환이라고 생각함.
- 요즘은 PC 이외에도 모바일 기기, iot 디바이스를 통해 웹 페이지를 접할 수 있는데 성능이 낮은 디바이스에서는 UI 변경이 쾌적하게 반영되지 못해 사용자에게 안좋은 경험을 제공하는 경우가 생길 수가 있음. 이를 퀀커런트 uI 패턴을 통해 사용자에게 더 나은 경험을 제공하고자 함. 퀀커런트 모드에서는 우선순위에 따른 화면 렌더, 컴포넌트의 지연 렌더, 로딩 화면의 유연한 구성 등을 쉽게 구성할수있도록 기능들을 제공해줌. 이 기능을 사용한 ui 개발 패턴을 퀀커런트 ui 패턴이라고 함.
- 이 방식은 선언형 프로그래밍 방식과 비슷함. 퀀쿼런트 유아이 패턴을 사용하지 않는 컴포넌트는 어플리케이션 상태에 따라 ‘어떻게’ 화면을 보여줄 지 집중하는 반면, 퀀커런트 유아이 패턴을 사용한 컴포넌트는 무엇을 보여줄지에 집중함 → 즉 state에 따라 UI를 화면에 그리는 것이 아니라 상황에 따라 적절한 ui를 화면에 보여줘야 함
- 이를 위해 suspense, errorboundary를 사용
- suspense: 컴포넌트가 렌더링하기 전에 다른 작업이 먼저 이뤄지도록 대기. fallback 을 통해 렌더링 전에 보여줄 화면을 구성함(스켈레톤 UI)
- error boundary: 비동기 작업이 에러날 시 보여주는 화면을 구성
TS / JS
- TS: JS 확장버전. 정적 타입을 지원하는 언어로, 개발자에게 타입 안정성과 코드의 가독성을 높여줌. 명시적인 타입 지정으로 타입 관련 에러 방지
- JS: 동적 타입 언어. 변수의 타입을 선언하지 않고 사용 가능. 유연함, 간편함을 제공하지만 타입 에러 가능성이 높아짐.
리액트 사용하는 이유는?
- UI를 자동으로 업데이트. 가상 돔을 통해 재사용이 필요한 기능들을 언제든지 필요한 곳에서 호출해서 반복적인 코드 작성 없이 사용할 수 있도록 해줌
- 단방향 데이터 흐름
- 컴포넌트 기반 아키텍쳐
- 자바스크립트와 XML 을 조합한 JSX 문법을 사용. JSX는 컴포넌트의 구조와 동작을 ‘선언적’으로 작성할 수 있게 해줌. ‘명령형(절차적)’ **프로그래밍**은 어떻게(HOW) 처리할지를 하나하나 코딩하는 방식이라면, ‘선언적’ **프로그래밍**은 “어떻게” 보다 “무엇(WHAT)”을 해야 하는=지를 지정하는 방식을 의미. 이는 가독성을 높이고, 컴포넌트의 렌더링을 보다 직관적으로 이해할 수 있도록 도와줌
DOM 이란?
- 웹사이트에 접속하면 각각의 요소들이 모여 하나의 문서를 구성함. 이러한 문서의 구조를 프로그래밍 언어가 이해할 수 있도록 표현한 것이 DOM.
- 돔 요소들은 트리 형태로 표현하며 각 요소에 해당하는 노드들이 존재함. 이러한 구조 때문에 특정 요소의 색상을 바꾼다고 가정하면 리플로우, 리페인트 비용이 많이 발생함
Virtual DOM 이란?
- 위의 DOM 의 문제를 해결하기 위해 나옴.
- 렌더링이 발생될 상황에 놓이게 되면 새로운 화면에 들어갈 내용이 담긴 가상 돔을 생성함. 가상 돔은 실제 DOM의 가벼운 복사본으로 메모리 상에 존재하며, JavaScript 객체 형태로 존재함. 리액트는 항상 렌더링 이전의 화면 구조와 렌더링 이후의 화면 구조를 가진 두 개의 가상 돔 객체를 유지하고 있음. 이 두 가상 돔을 비교하여 변경된 부분만 실제 DOM에 반영함 (diffing 알고리즘 사용)
리액트와 넥스트의 차이는?
- 리액트: Javascript 기반의 SPA 라이브러리. 리액트는 CSR(Client Side Rendering), 즉 화면을 그리는 렌더링이 클라이언트에서 발생합니다. 서버에서 보내주는 HTML과 Javascript 파일을 서버가 아닌, 클라이언트의 브라우저에서 페이지를 만들어줍니다. 이러한 방식은 페이지 간 전환이 부드러워지는 장점이 있습니다. 하지만 HTML과 JS를 다운로드 받는동안 클라이언트는 렌더링이 불가능한, 즉 첫 페이지의 로딩속도가 느리다는 단점이 있습니다. 또한 CSR의 특성상 빈 HTML과 JS를 보낸 뒤 클라이언트의 브라우저에서 JS를 실행시켜 화면을 그리는데, 대부분의 검색 엔진은 HTML 파일만 크롤링합니다. Meta 태그 또한 크롤링 봇이 가져가지 못하기에, meta 태그를 이용하는 마케팅 툴또한 사용할 수 없습니다. 이러한 점들은 SEO(Search Engine Optimization)에 악영향을 끼쳐 구글과 같은 검색 사이트의 상위 노출에 불리해집니다. 이는 웹 비즈니스에 있어 매우 큰 단점으로 작용합니다. 이러한 단점들을 극복하기 위해 최근 들어 React Meta-Framework(Gatsby, Next.js, Remix) 들이 나왔습니다.
- Next: SSR(Server Side Rendering)으로 동작하는 리액트 프레임워크. SSR은 서버 측에서 즉시 렌더링 가능하게끔 가공한 html파일을 만들어 브라우저에게 보내고, 브라우저는 이를 다운하여 즉각 화면에 렌더링할 수 있는 방식입니다. 또한 Next.js는 Code splitting이라는 기술을 통해 초기 로드 시 필요한 최소한의 코드만 다운로드하여 실행하므로, 앱의 초기 로딩 속도를 개선함과 동시에 React보다 가볍게 동작할 수 있습니다. SSR이기에 SEO 또한 훌륭합니다. 심지어 13버전부터 원하는 페이지에서 CSR이 가능하기 때문에 Next.js의 장점만 쓸 수 있어졌다고 할 수 있습니다.
- Next의 필요성중요한 것은 프론트엔드, 백엔드 개발에서 필요한 잡다한 설정들에 드는 수고를 크게 줄여줍니다.
- 리액트에서의 라우팅, 바벨, 웹팩등의 설정부터, 백엔드의 미들웨어 설정, SEO, SSR 등 많은 것을 Next가 해결해줍니다.
- Next.js는 풀스택 프레임워크로, 백엔드 개발도 가능합니다.
SPA 란?
- 단일 페이지 애플리케이션(Single Page Application)으로 서버에서 필요한 데이터만 비동기로 받아와서 동적으로 현재 화면에 다시 렌더링 하는 방식. 사용자가 애플리케이션과 상호작용할 때마다 서버에 요청하여 전체 HTML 화면을 받아오는 방식이 아니라, 화면 렌더링을 로컬 PC에서 즉시 생성하므로 더 빠르게 화면 전환을 처리할 수 있어서 널리 사용됨
- SPA가 ‘단일 페이지 애플리케이션’이라고 일컬어지지만, 하나의 페이지만 존재하는 애플리케이션을 의미하지는 않음. SPA(Single Page Application)도 여러 페이지가 존재함. 다수의 페이지를 표시하는 데 있어서 과거 전통적인 방식으로 페이지 전환을 수행하지 않고, 마치 하나의 페이지인 것처럼 처리하는 기술을 의미
프레임워크 vs 라이브러리
- 프레임워크
- 소프트웨어 개발에 있어서 하나의 뼈대. 클래스와 라이브러리가 합쳐진 형태 개발자가 소프트웨어를 개발함에 있어 코드를 구현하는 개발 시간을 줄이고, 코드의 재사용성을 증가 시키기 위해 일련의 클래스 묶음이나 뼈대, 틀을 라이브러리 형태로 제공되는 것을 말한다.
- Java 개발에서 사용되는 Spring 프레임워크나 Python 개발에 사용되는 Django, 안드로이드 앱개발에 사용되는 Android 등이 있다.
- 라이브러리C++의 STL 이나 Python의 Pip로 설치한 패키지/모듈(pandas, tensorflow 등)이 있다.
- 개발에 필요한 것들을 미리 구현해놓은 도구라고 할 수 있다. 재사용이 가능한 기능을 미리 구현해놓고 필요한 곳에서 호출하여 사용 가능하도록 만들어진 집합이다.
- 차이점프레임워크는 제어의 역전(IoC : Inversion of Control) 개념이 적용되어 있다. 즉, 프레임워크에게 제어의 흐름을 넘겨 개발자가 작성하는 코드에서 신경 써야 할 부분을 줄인다는 뜻이다.프레임워크는 전체적인 흐름을 쥐고 있으며 애플리케이션의 코드는 프레임워크에 의해 사용된다. 애플리케이션 코드는 프레임워크가 짜놓은 틀 안에서 수동적으로 동작하기 때문에 제어의 흐름은 프레임워크에게 있다.
- 반면 라이브러리는 개발자가 전체적인 흐름을 만들며 라이브러리를 가져다 쓰게 된다. 즉, 개발자에게 전적으로 제어 흐름이 있으며 필요할 때마다 능동적으로 라이브러리를 호출하여 사용한다.
- 프레임워크는 라이브러리를 포함한다. 프레임워크 위에 개발자가 작성한 애플리케이션 코드가 올라가게 되고, 이 애플리케이션 코드에서는 라이브러리를 호출할 수 있다. 이처럼 프레임워크와 라이브러리의 가장 큰 차이점은"제어 흐름"이 어디에 있는가이다.
REST API 란?
- 서버와 통신하는 방식 중 한 가지로 http메서드를 사용하여 데이터를 요청/전송합니다. 기존에 많이 사용하던 SOAP API 의 경우 서비스 인터페이스를 이용해 서버에 접근했다면, REST는 인터넷 식별자(URI)와 HTTP 프로토콜을 이용해서 접근하는 것이 특징이며 사용법이 단순하여 높은 보안수준을 요구하는 작업이 아닐 경우 일반적으로 많이 선호되는 통신방법입니다. 데이터포맷은 브라우저 호환성이 좋은 JSON을 사용하며 resource, method, message로 구성됩니다.
동기 / 비동기 특징
- 동기의 (대략적인) 특징
- 동시에 여러 작업을 수행할 수 없다.
- 흐름을 예측하기 쉽다. 먼저 수행되고 나중에 수행되는 것들이 명확하다.
- 비동기의 (대략적인) 특징
- 동시에 여러 작업을 수행할 수 있다.
- 흐름을 예측하기 어렵다. (무엇이 먼저 완료될 지 보장할 수 없다.) → 코드의 실행 순서를 보장받지 x
- 비동기 처리는 JS의 특징 중 하나. 특정 연산이 끝날 때 까지 코드의 실행이 멈추지 않고 다음 코드를 먼저 실행한다. 비동기 처리가 가진 문제점을 callback 함수가 해결함. 콜백 함수는 콜백 이후에 처리될 작업들을 콜백 함수 내에 작성함. 근데 이 과정이 반복되면 콜백 지옥이 발생함. 1번 코드의 정보를 바탕으로 2번 코드가 발생하고 또 3번코드는 2번 코드의 정보를 바탕으로 실행되다보면 발생하는 것임. 이를 보완하기 위해 promise, async/await가 나타남
Promise
- Promise는 자바스크립트에서 비동기 처리에 사용되는 객체
- 코드는 실행 되었지만 결과를 아직 반환하지 않은 객체
- Pending(대기)
- Fulfilled(이행)
- Rejected(실패)
- 만약, reject가 호출되면 catch메소드의 동작만 실행됩니다.
- Promise가 끝난 후 동작을 설정할 수 있는데, 이는 then메소드와 catch메소드 입니다.
- 비동기 처리가 완료되어 값을 반환한 상태인 Fulfilled,
- Promise는 3가지 상태가 있습니다.
async 와 await
- async 키워드는 함수를 선언할 때 붙임
- 함수에 async 키위드를 붙이고, Promise 생성자 함수를 제거합니다.
- resolve(value); 를 return value; 로 변경합니다.
- reject(error); 부분을 throw new Error(); 로 수정합니다.
- await은 Promise가 fulfilled 또는 rejected이 될 때까지 기다리는 함수 - 비동기 처리 코드 앞에 붙임
- 사용 이유
- async는 에러 위치를 찾기 쉽고 리턴값에 변수를 담아 사용하므로 가독성이 좋음
- 에러 핸들링에 유리함
상태의 종류
- 지역 상태
- 특정 컴포넌트 안에서만 관리되는 상태를 뜻한다. 다른 컴포넌트들과 데이터를 공유하지 않는다. 예를 들면, input, selectbox 등에서 사용자의 입력값을 받는 경우가 있다. (보통 Form 데이터들이 지역상태에 속한다.)
- 컴포넌트 간 상태
- 여러가지 컴포넌트에서 관리되는 상태를 나타낸다. 다수의 컴포넌트에서 쓰이고, 또 영향을 미치는 상태를 뜻한다. 프로젝트 곳곳에서 쓰이는 모달을 예로 들 수 있다. 보통 상위 컴포넌트에서 하위 컴포넌트로 prop을 넘겨 해당 컴포넌트까지 전달되도록 하는 Prop Drilling 방식을 필요로 한다.
- 전역 상태
- 프로젝트 전체에 영향을 끼치는 상태이다. 예를 들면, 유저 기능을 생각하면 된다. 이 또한 Prop Drilling 방식을 활용해서 부모에서 자식으로 데이터를 전달한다.
Prop Drilling이란, props를 오직 하위 컴포넌트로 전달하는 용도로만 쓰이는 컴포넌트를 거치며 컴포넌트에서 다른 컴포넌트로 데이터를 전달하는 과정이다.
[상위 컴포넌트 > 중간 컴포넌트 > 중간 컴포넌트 > ... > 타겟 컴포넌트] 이런 식이다.
이런 prop 전달 과정이 많지 않다면 큰 걱정은 없지만, 만약 어플리케이션이 커져서 정말 많은 과정을 거치게 되어야 한다면, 그 코드의 prop을 추적하기는 정말 힘들 것이다.
상태관리는 왜 필요한가?
- 서로 다른 두 컴포넌트에 같은 데이터가 필요하다고 할 때, 각 컴포넌트가 부모자식 관계로 되어있지 않은 이상, 각 컴포넌트 간의 직접적인 데이터 전달은 어렵다. 데이터를 부모 컴포넌트로 보내고, 다시 그 상데이터 필요한 컴포넌트로 전달해야한다. 하지만 이렇게 Prop Drilling이 많아지면 이 prop이 어디에서 왔는지 확인하기 정말 어려워진다.그렇기때문에 각 어플리케이션에 알맞은 상태관리 툴을 선택해 상태를 잘 관리하는 것이 중요하다.가장 대표적이고 또 많이 쓰이는 도구: Context API, Redux, React Query
- 상태관리를 위한 도구는 정말 다양하다.
- 물론 상태가 어디에서 왔고, 어디를 거쳐서 어디까지 갔고.. 이런걸 다 기억하고 있을 수 있다면 정말 좋겠지만, 상태가 많아지고 어플리케이션이 복잡해질수록 prop을 추적하기는 점점 힘들어질 것이다.
Context API
- Context API는 리액트에서 만든, React 컴포넌트 트리 안에서 전역 상태를 공유할 수 있도록 만들어진 방법이다."전역 상태관리 도구"라고 말하기는 살짝 애매한 감이 있는데, 이는 Context API는 아무것도 관리하지 않기 때문이다. Context API는 종속성을 주입하기위한 도구일 뿐이다. React에서의 실질적인 상태관리는 useState, useReducer를 통해 일어난다. 보통 "상태관리" 라고 함은, 변화하는 데이터들을 관리하는 것인데, 상태의 초기 값을 저장하거나, 현재 상태의 값을 읽거나, 새로운 데이터로 상태를 업데이트 하는 등의 행위를 뜻한다. 하지만 Context는 이런 상태들을 직접적으로 관리해주지 않고, 단순히 이미 존재하는 상태를 다른 컴포넌트들과 쉽게 공유할 수 있게 해주는 역할을 한다. 이런 Context API는 중간에 있는 Element들에게 props를 넘겨주지 않고도 데이터를 가져다가 사용할 수 있기 때문에 (Prop Drilling을 피할 수 있다.) 테마나 언어 등 전역적으로 쓰이는 데이터들을 사용할 때 자주 쓰인다. 다만 Context를 사용하게되면 컴포넌트를 재사용하기가 매우 힘들어지기때문에, 마구 사용하는 건 지양해야한다. Context API는 Context, Provider, Consumer로 설명할 수 있다.
- Context는 전역 상태를 저장하는 곳이다. Context 내부에 Provider와 Consumer가 정의되어있고, Consumer는 Context를 통해서 상태에 접근이 가능하다.
- Provider는 전역 상태를 제공하는 역할을 한다. Context에 상태를 제공해서 다른 컴포넌트가 상태에 접근할 수 있도록 도와준다. 제공된 상태에 접근하기 위해서는 Provider 하위에 컴포넌트가 포함되어있어야한다. 보통 모든 컴포넌트에 접근해야하는 상태를 제공하기 위해서는 Root Component (index.js / app.js)에서 Provider를 정의한다.
- Consumer는 제공받은 전역 상태를 받아서 사용하는 역할을 한다. Context는 Consumer 사이에 있는 첫 객체를 Context에 인자로 전달하기 때문에, 바로 JSX를 작성하면 안되고, 빈 객체를 작성하고나서 JSX를 작성해야한다.
- 이런 Context API는, 그 범위를 제대로 지정하지 않는다면, 불필요한 rerender를 일으키기도 한다. 각 Context를 잘 나누고 또 필요하다면 useMemo 등을 사용해 코드를 작성하는 것이 좋다. 하지만 useMemo 또한 연산이 들어가는 작업이기 때문에, 정말 필요한 곳에 잘 사용하는 것이 중요하다. 곧 살펴볼 Redux도 코드를 뜯어보면 Context API를 기반으로 만들어져있다고 한다. (Context API를 사용하면서 이것저것 신경쓰느니 차라리 Redux를 사용하는 편이 나을지도..?!)
Redux
- Redux는 전역 상태관리를 위한 도구이다. 어플리케이션 전체에 대한 중앙 저장소 역할을 한다. Redux 공식 페이지에보면, Redux는 "자바스크립트 앱을 위한 예측 가능한 상태 컨테이너" "액션"이라는 이벤트를 사용해서 어플리케이션의 상태를 우리가 예측 가능한 방식으로 업데이트 할 수 있게 도와준다. Redux는 라이브러리이기 때문에 다양한 UI Framework / Library들과 함께 사용이 가능하다.
- Store는 저장소, 즉 전역상태를 저장하는 공간이다. 자바스크립트 객체 형태로 저장되어 있으며, 오직 Reducer를 통해서만 접근할 수 있다. 보통은 최상단의 index.js에 정의한다. 여러개의 Context를 만들 수 있는 Context API와는 다르게 Redux에서 Store는 1개만 존재할 수 있다.
- Action은 Reducer에게 보내는 Store에 대한 행동을 정의하는 자바스크립트 객체이다. 우리는 상태에 어떤 변화가 필요할 때, 액션을 발생시킨다. "이렇게 상태를 변경해줘~" 라고 하는 어떤 주문서의 역할을 한다고 보면 이해가 쉽다. Action을 Reducer에게 전달하기 위해서는 dispatch 메소드를 사용해야한다. dispatch는 Store의 내장 함수 중 하나인데, 액션 객체를 넘겨줘서 상태를 업데이트한다. 이벤트를 일어나게하는 이벤트 트리거의 역할을 한다.
- Reducer는 이전 상태와 액션을 받아, 다음 상태를 반환하는 역할을 하는 순수 함수이다. Reducer를 통해서만 전역 상태를 변경하고 업데이트할 수 있다. 어떤 액션이 들어오는지 그 유형에 따라 이벤트를 처리하는 이벤트 리스너라고 볼 수 있다. 여기서 중요한 점은, 이전 상태를 변경한다는 점이 아니라, 새로운 상태 객체를 생성해서 반환해야한다는 사실이다.
- 순수함수란, 다른 외부의 상태를 변경하지 않으면서도, 어떤 동일한 인자에 대해 항상 동일한 값을 리턴하는 함수이다.
React Query
- 전역 상태관리 라이브러리라고 보기보다는, 서버와 클라이언트 간 비동기 작업을 쉽게 다룰 수 있게 도와주는 라이브러리다. 서버상태를 관리하는 라이브러리라고 생각하면 된다. 프론트엔드에서 어려운 부분 중 하나가, 이렇게 비동기를 통해 서버 상태를 가져오고 관리하고 업데이트 하는 부분인데, 고 부분을 쉽게 해준다.서버 상태는 내가 직접 관리할 수 있는 것이 아니기 때문에, 데이터의 만료에 따른 업데이트나 캐싱, 서버 데이터를 호출하는 과정 등에 특별히 신경을 써가며 관리를 해야한다. 물론 신경을 쓰지 않아도 되지만 완성도 높은 어플리케이션을 만들기 위해서는 필요한 작업이라고 할 수 있겠다.
- API 데이터의 만료시간
- 데이터를 캐시에서 유지할 시간
- 브라우저를 focus할 때, 데이터를 리프레시 할 것인지에 대한 여부
- 리프레시 간격
- 데이터 가져오는 것에 대한 성공, 로딩, 에러 콜백 등..
- 정말 간단한 코드 몇줄로 이게 모두 가능하다.
- React Query는 useQuery hook의 파라미터를 통해 다양한 기능을 제어할 수 있다.
- 보통 Redux와 같은 전역상태관리 라이브러리들이 클라이언트의 상태에 대해서는 잘 동작하지만, 서버 상태에 대해서는 그렇게 동작하지 못하기 때문에(명시적으로 fetch를 해야지 서버의 데이터를 최신으로 반영한다거나, 많은 컴포넌트에서 최신 데이터를 받아오기 위해 여러번 fetch를 한다던가.. 하는 등의 최적화가 어려워서), 이와 같은 서버상태관리 라이브러리가 나타나게 되었다고 볼 수 있다.
리액트의 생명주기
- 컴포넌트는 생성(mounting) -> 업데이트(updating) -> 제거(unmounting)의 생명주기를 갖습니다. 리액트 클래스 컴포넌트는 라이프 사이클 메서드를 사용하고, 함수형 컴포넌트는 Hook을 사용합니다.
Functional Component 생명주기
- Hook: 함수형 컴포넌트에서 react state와 생명주기 기능을 연동할 수 있게 해주는 함수. class 안에서 작동하지 않고 class 없이 리액트 사용이 가능함
- 리액트 훅을 도입한 목적: 기존의 라이프사이클 메서드 기반이 아닌 로직 기반으로 나눌 수 있어서 컴포넌트를 함수 단위로 잘게 쪼갤 수 있음. 라이프사이클 메서드에는 관련 없는 로직이 자주 섞여 들어가는데 이는 버그 발생률을 높이고 무결성을 해침
- Hook 사용 규칙
- 최상위에서만 훅 호출(반복문, 조건문, 중첩 함수 내에서 사용하면 x)
- 리액트 함수 컴포넌트에서만 호출
- Hook의 종류
- useState: 상태를 관리. [state이름, setter이름] 순으로 반환 받아서 사용
- useEffect: 화면에 렌더링이 완료된 후에 수행됨
- useContext: Context API를 통해 만들어진 Context에서 제공하는 Value를 가져올 수 있음
- useReducer: useState의 대체 함수로 컴포넌트 상태 업데이트 로직을 컴포넌트에서 분리시킬 수 있음
- useRef: 특정 DOM 선택할때 주로 쓰이며 .current 프로퍼티로 전달된 인자로 초기화된 변경 가능한 ref 객체를 반환
- useMemo: 메모이제이션된 값을 반환. 이미 연산 된 값을 리렌더링 시 다시 계산하지 않도록 한다. 의존성이 변경되었을 때에만 메모이제이션된 값만 다시 계산. 의존성 배열이 없는 경우 매 렌더링 때마다 새 값을 계산
- useCallback: 메모이제이션 된 콜백을 반환. useMemo와 유사하게 이용되며 '함수'에 적용
useState와 useRef의 차이
- 렌더링 횟수 차이useRef: 값의 변화에 의한 리렌더링이 발생하지 않음. 렌더링과 관련 없는 값을 저장하기에 적합
- setTimeout,setInterval이 반환하는 ID 값
- state의 이전 값
- 렌더링과 무관한 가변값
- useState: 상태값이 변경될 때 마다 새로 화면을 불러옴
쿠키와 세션, 세션스토리지, 로컬스토리지
- 쿠키: 클라이언트와 서버 연결이 끊겨도 필요한 정보를 기억하기 위해 서버에서 데이터를 묶어서 클라이언트의 컴퓨터 혹은 브라우저의 메모리에 저장되는 key-value로 이뤄진 텍스트 파일. 만료시간 정보를 가지고 있기 때문에 브라우저를 종료해도 데이터가 유지됨
- 세션: 서버에서 데이터를 관리하고 고유 ID를 생성해 클라이언트를 식별하는 방법. 세션쿠키는 브라우저 종료 시 삭제됨
- 쿠키와 세션의 차이: 둘다 쿠키를 이용하지만 데이터를 누가 관리하는지에 차이가 있음
- 세션 스토리지: 새창, 새탭 단위로 스토리지가 생성되며 데이터 공유가 안됨. 같은 탭이라도 도메인이 다르면 또 다른 세션 스토리지가 생성됨. 창이나 탭을 닫으면 저장된 객체가 사라짐
- 로컬 스토리지: 웹 도메인 당 1개씩 생성. 세션스토리지와 다르게 새 창을 열어도 도메인이 같으면 동일한 데이터를 공유하고 다른 도메인의 로컬 스토리지에는 접근할 수 없음. 또한 직접 로컬 스토리지를 삭제하지 않으면 데이터가 영구적으로 저장됨
Custom hook과 utils
- 커스텀 훅: 상태 로직을 재사용할 수 있도록 하는 기능. 여러 컴포넌트에서 공통적으로 사용되는 상태 로직을 추출해 하나의 함수로 만들어서 사용. 보통 use 라는 접두사를 사용해서 함수 이름을 정의함. 코드의 중복을 줄일 수 있으며 컴포넌트의 재사용성과 유지보수성을 높일 수 있음
- 유틸 함수: 리액트에서 자주 사용되는 기능들을 모듈화해서 재사용할 수 있도록 도와주는 함수
- 차이점커스텀 훅: React hooks를 사용하여 구성 요소에 특정 동작이나 기능을 제공하는 함수 - useState, useEffect등의 훅을 사용하는 로직을 따로 뺴둔거
- 유틸 함수: 애플리케이션의 어느 곳에서나 사용할 수 있는 독립 실행형 함수 - 즉 그냥 로직을 따로 빼둔거
라이브러리 사용 경험 및 라이브러리 선정할 때 중요하게 여기는 점은?
- 슬라이더(케러셀) - 프로젝트시에 이미지 슬라이더 기능이 필요한 적이 있어서 사용한 경험이 있음
- 네브바 -
이벤트 버블링과 캡쳐링이란?
- HTMl 요소들이 중첩되어있다면 이벤트 핸들링은 어떻게 동작할까 - 이벤트 전파 발생
- 이벤트 버블링: 이벤트가 발생한 요소부터 점점 부모 요소를 거슬러 올라가서 window 까지 이벤트를 전파
- 버블링을 강제로 중단시키는 방법: 이벤트 객체의 메서드인 **event.stopPropagation()**를 사용
- 이벤트 캡쳐링: 버블링과 반대로, window 부터 이벤트가 발생한 요소까지 이벤트를 전파
REST 란?
- 자원을 이름으로 구분하여 해당 자원의 상태를 주고받는 모든 것을 의미
- HTTP URI(Uniform Resource Identifier)를 통해 자원(Resource)을 명시하고,
- HTTP Method(POST, GET, PUT, DELETE, PATCH 등)를 통해
- 해당 자원(URI)에 대한 CRUD Operation을 적용하는 것을 의미
- 특징
- Server-Client(서버-클라이언트 구조)
- Stateless(무상태)
- Cacheable(캐시 처리 가능)
- Layered System(계층화)
- Uniform Interface(인터페이스 일관성)
CRUD 란?
- 클라이언트가 서버에게 요청을 보낼 때 이 요청들을 크게 4가지 성격으로 분류
- Create(POST 메소드): 서버에 정보를 올려달라는 요청
- Read(GET): 서버에서 정보를 불러오는 요청
- Update(PUT, PATCH): 정보를 바꾸는 요청
- Delete(DELETE): 정보를 지우는 요청
- 서버에서 클라이언트로 데이터를 보낼 때 json 양식으로 보냄
React class component vs React function component
- 리액트에서는 컴포넌트를 클래스와 function 으로 만들 수 있음
- Class: React에서 제공하는 Component라는 클래스를 extends, 상속해서 만들 수 있음클래스형 컴포넌트는 반드시 render() 메서드가 존재해야만 하고 이 메서드를 통해 jsx가 렌더링된다.
- 그렇지만 함수형 컴포넌트에서는 return 문 안에 jsx를 포함하기만 하면 된다.
- class Clock extends React.Component { render() { return ( <div> <h1>Hello, world!</h1> <h2>It is {this.state.date.toLocaleTimeString()}.</h2> </div> ); } }
- Life Cycle이것은 클래스형 컴포넌트와 함수형 컴포넌트 모두 해당되는 사항이다.예컨대, 컴포넌트가 마운트되는 순간 콘솔로그를 출력하고 싶다.그리고 클래스형 컴포넌트에서 라이프 사이클을 컨트롤 할 수 있는 방법은 직접 메서드를 이용하는 것이다.
- 클래스형 컴포넌트에는 라이프 사이클과 관련된 메서드가 굉장히 많지만, 현재는 일반적으로 사용되는 메서드는 3개 정도이다(componentDidMount(), componentDidUpdate() , componentWillUnmont()
- 라고 할 때 특정 메서드나 useHooks을 통해 제어할 수 있는 것이다.
- 라이프 사이클이 무엇인지 간단하게 설명하자면 컴포넌트가 마운트(화면에 렌더링)되고 언마운트(마운트 해제)될 때까지의 주기를 말한다.
- 컴포넌트에는 라이프 사이클이 있다.
react-router-dom 이란?
- react는 SPA(Single Page Application)이다.
- react에 router를 사용할 수 있는 즉, 화면 전환을 지원하는 모듈이다.
- 라우팅이란 사용자가 요청한 url에 따라 해당 url에 맞는 페이지를 보여주는 것이다.
- 리액트로 SPA를 개발할 때 라우팅을 위해 react-router 라이브러리를 사용한다.
let, const, var의 차이, 호이스팅이란 ?
- var재선언되고, 업데이트될 수 있음
- 변수가 함수 외부에서 선언될 때의 범위는 전역입니다. 즉, 함수 블록 외부에서 var를 사용하여 선언된 모든 변수를 전체 윈도우 상에서 사용할 수 있는 것. var가 함수 내에서 선언될 때는 함수 범위로 지정됩니다. 즉, 해당 함수 내에서만 사용하고 접근할 수 있음
- 호이스팅: 변수와 함수 선언이 맨 위로 이동되는 자바스크립트 매커니즘. 오직 var 변수에서만 호이스팅이 일어난다.
- let업데이트될 수 있지만, 재선언은 불가능
- 선언된 변수는 해당 블록({ }) 내에서만 사용가능
- 동일한 변수가 다른 범위 내에서 정의된다면, 에러 발생 x
- const블록 범위 const:let 선언처럼 const 선언도 선언된 블록 범위 내에서만 접근 가능
- 업데이트, 재선언 불가능!
- 변수는 일정한 상수 값을 유지
Fetch / Axios
- 프로미스 기반 HTTP 클라이언트로 네트워크 통신을 도와주는 api
- Axios
- json 을 바로 적용해서 response 객체를 바로 반환
- fetch 보다 편리한 api와 기능을 제공, 프로미스 기반으로 비동기 작업을 처리
- fetch
- .json() 메서드를 사용해 응답 데이터를 json 형식으로 파싱해야 함
useTransition
- ui를 차단하지 않고 상태를 업데이트 할 수 있는 리액트 훅
- Concurrent rendering(동시성 렌더링) 사용
- startTransition 을 suspense 와 함께 사용할경우 불필요한 로딩 인디케이터 노출을 막을 수 있음
- 일반적으로 렌더링이 오래걸리는 컴포넌트를 서스펜스로 감쌀 경우 해당 컴포넌트가 렌더링 될 때마다 서스펜스의 fallback 을 만남. 해당 렌더링이 종료될 때 까지 폴백 컴포넌트를 마주해야 하는데, 오래 걸리는 상태 업데이트를 startTransition으로 감쌀 경우 서스펜스를 통해 컨텐츠를 숨기지 않고 이전 컨텐츠를 계속 표시하게 됨
export / export default
- 한 파일 안에 export 와 export default 혼용이 가능함
- 가장 큰 차이점은 위의 예시에 보인 것 처럼
- export: 수출하는 모듈안에 수출할 개체가 하나이든 여러개이든 상관 x
- export default: 수출하는 모듈 안에 객체가 딱 하나만 들어있어야 함
JSX란?
- JSX는 JavaScript XML의 약자로 자바스크립트에서 XML을 추가한 확장형 문법. 큰 특징은 자바스크립트에서 HTML 문법을 사용할 수 있다는 점이고 주로 리액트나 다른 프론트엔드 프레임워크에서도 사용 가능
모듈(module)
- *'자바스크립트 파일 하나'*를 모듈이라 함
- 모든 함수나 변수같은 것들을 index.js파일 하나에 때려 넣으면 파일이 복잡하고 보기가 힘드니까 그것들을 모듈로 만들어서 따로 빼 놓고 index.js에서 끌어다 쓰는 것이다. 여기서 사용되는 것이 export와 import지시자이다. 모듈 파일에서 선언된 변수나 함수 앞에 export를 붙여서 수출하고 그 것을 불러올 모듈에서 import하여 수입해오는 것이다.
'Frontend' 카테고리의 다른 글
캐시된 데이터로 인한 북마크 상태 미반영 문제 해결 (2) | 2024.10.21 |
---|---|
Refresh Token 프론트엔드 접근 방식 (0) | 2024.09.25 |
SSR, SSG, ISR (6) | 2024.09.02 |
CSR vs SSR (0) | 2024.08.30 |