본래 React를 쓰면서 'state 끌어올리기'에 부담을 느끼거나, 불필요한 props drilling 등이 이슈가 되면서 전역적인 state 관리법이 필요해졌고, 그에 대한 해답(?)으로 나온 것이 Redux라고 할 수 있다(React + Flux 패턴).
: 모든 상태 업데이트를 액션으로 정의하고, 액션 정보에 기반하여 리듀서에서 상태를 업데이트하는 이 간단명료한 발상 덕분에, 상태를 더욱 쉽게 예측 가능하게 하여 유지보수 측면에 긍정적인 효과가 있다. 이게(흔히 말하는 Reducer + FLUX 패턴) 마음에 드는 사람들은 계속 리덕스를 사용하면 된다.
: Redux-saga, Redux-thunk 와 같은 미들웨어를 통해 비동기 작업에 대한 좀 더 디테일하고, 편한 컨트롤을 할 수 있다. 예를 들어, redux-saga를 쓰는 이유를 생각해보면, 아래와 같은 부분에서 좀 더 편하고, 명확한 개발을 할 수 있게 해준다
리덕스를 사용하면 상태 값과 값을 업데이트하는 로직을 관리해주어 값을 불러올 때나 업데이트 할 때 컴포넌트를 거치지 않고 쉽게 할 수 있다.
Ducks 패턴
기능에 따라 액션타입, 액션, 리듀서를 한 곳에서 작성하여 하나의 모듈로 관리하는 것. 기능에 따라 한 파일로 작성하므로 수정사항이 있으면 여러 파일을 수정하지 않고 한 파일만 수정하면 되어 편리하다.
규칙: 리듀서 함수를 default export 해야 한다. 액션 생성함수를 export 해야 한다. 접두사를 붙인 형태로 액션 타입 정의, 액션 타입은 UPPER_SNAKE_CASE 형태로 이름짓고 export한다.
state, props drilling, 상태관리
https://tech.trenbe.com/2022/05/25/Redux-Saga.html
키워드 :
코드량, state, props
Context API의 특징
React에서만 사용할 수 있습니다. (리액트 내장 기능)
Entry 파일(root)에서 구성한 Provider를 내려 주는 형식입니다.
사용하고자 하는 컴포넌트에서 작성한 Dispatch와 State를 꺼내서 사용합니다.
reducer를 여러 개 만들면 Provider에서 여러 단계로 만들어 사용할 수 있습니다.
React, Vue와 같은 프레임워크 환경에서 사용할 수 있습니다.
상태를 저장하는 Store를 따로 가지고 있습니다.
thunk, saga와 같은 미들웨어를 추가적으로 사용하여 구성할 수 있습니다.
Redux devtool extension을 사용하면 상태에 대한 디버깅이 가능합니다.
전역 상태 관리 외에도 로컬스토리지 상태저장, 버그리포트 첨부 기능 등의 기능들을 사용할 수 있습니다.
키워드 :
React, 컴포넌트, 상태관리
리덕스 썽크(Redux Thunk) 다음으로 가장 많이 사용되고 있는 리덕스 사가(Redux Saga)는 리액트/리덕스 애플리케이션에서 비동기적으로 API를 호출하여 데이터를 가져오는 일과 같은 부수 효과(Side Effect)를 쉽게 처리하기 위해 사용하는 라이브러리입니다. 때에 따라 기존 요청을 취소 처리해야 한다거나 여러 개의 API를 순차적으로 호출해야 하는 등의 좀 더 까다로운 비동기 작업을 다루는 상황에 유용합니다.
리덕스 사가(Redux Saga)는 애플리케이션에서 전적으로 부수 효과(Side Effect)만을 담당하여 처리합니다. 비동기 함수 호출 결과 데이터를 통해 성공, 실패 여부를 판단하고 상태를 업데이트시키는 등의 작업(Task)을 제어할 수 있으며, 스토어에 접근하거나 특정 액션(Action)을 디스패치(Dispatch) 하여 다른 사가함수를 실행시킬 수 있습니다.
리덕스 사가(Redux Saga)는 부수 효과들을 처리하기 위해 제너레이터(Generator)라는 ES6 기능을 사용합니다. 제너레이터를 사용하게되면 비동기의 흐름을 표준 동기 코드처럼 보이게 하여 비동기 흐름을 쉽게 읽고 쓰고 테스트할 수 있어 복잡한 워크플로를 관리하는 데 매우 효과적입니다.
redux saga: 액션을 모니터링하고 있다가 특정 액션이 발생하면 정해진 로직에 따라 특정 작업을 수행할 수 있게 하는 미들웨어. 제너레이터 문법을 기반으로 하여 yield 키워드를 사용해 비동기를 처리할 수 있다.
키워드 :
제네레이터 문법, API, 특정 작업
function* 키워드를 사용하여 만든 제너레이터 함수를 호출했을 때는 한 객체가 반환되는데요, 이를 제너레이터(Generator) 또는 이터레이터(iterator) 객체라고도 부릅니다. 제너레이터의 내부 코드를 실행하기 위해서는 이 객체가 가지고 있는 next 메서드를 호출 해야만 하는데요. next 메서드의 호출 시마다 순차적으로 원소들을 탐색하고, yield키워드를 반환 포인트로 여기며 value 와 done 프로퍼티를 가진 새로운 객체를 반환합니다.
다시 말해서 제너레이터 안에서 yield 키워드를 사용하면 yield 키워드를 포인트로 코드의 흐름이 멈추게 되고 멈춘 코드의 흐름을 이어 나가기 위해서는 다시 next 메서드를 호출하는 방식으로 일시 정지와 재시작 기능을 사용할 수 있습니다.
https://www.youtube.com/watch?v=4_WLS9Lj6n4
키워드 :
next(), 함수, yield
리덕스의 미들웨어입니다.
리덕스가 액션을 수행하면 redux-saga에서 디스패치하여 redux의 액션을 가로챈 뒤, 액션의 역할을 수행 하고
다시 액션을 발행하여 데이터를 저장하거나 다른 이벤트를 수행시킵니다.
가장 간단히 얘기하면 해당 미들웨어는 객체 대신 함수를 생성하는 액션 생성함수를 작성할수 있도록 도와줍니다.
리덕스에서는 기본적으로 액션 자체를 디스패치합니다.
일반 액션생성자는 다음과 같이 파라미터를 가지고 액션 객체를 생성하는 작업만 합니다.
만약 특정 액션이 몇초뒤에 실행하게 하거나, 현재 상태에 따라 무시되게 하려면 일반 액션생성자로는 할 수 없습니다.
redux-thunk 는 이를 가능하게 합니다.
키워드 :
액션, 수행, 함수, 제네레이터
https://jw910911.tistory.com/48
싱글페이지 애플리케이션의 약어로 한 개의 페이지 내에서 필요한 자원들을 동적으로 응답받는 애플리케이션이라는 의미이다. 서버에서 완성된 HTML을 받아오는 것이 아니라 서버에 의해 HTML과 자바스크립트 파일이 로드되면 사용자의 상호작용에 의해 자바스크립트 코드에 따라 동적으로 브라우저에서 렌더링되는 클라이언트 사이드 렌더링을 기반으로 동작한다.
전통적인 웹페이지는 여러 페이지로 구성되어있어 사용자가 다른 페이지로 이동할 때마다 새로운 html을 받아오고 사용자에게 보여지는 화면을 서버측에서 준비했다. 요즘 웹사이트는 제공되는 정보가 많으므로 화면을 보여주어야 할 때마다 서버 측에서 모든 뷰(화면구성)를 준비한다면 성능에 문제가 발생할 수 있다. 리액트 같은 라이브러리 혹은 프레임워크를 사용하여 우선 애플리케이션을 브라우저에 불러와서 실행시킨 후에 사용자와의 상호작용이 발생하면 필요한 부분만 자바스크립트를 사용하여 업데이트해준다.
새로운 데이터가 필요하다면 서버 api 를 호출하여 필요한 데이터를 새로 불러와 사용할 수도 있다.
단점: 사용자가 실제로 방문하지 않을 수도 있는 페이지의 스크립트도 불러오기 때문에 앱의 규모가 커지면 성능이 나빠질 수 있다. 코드 스플리팅을 사용하면 라우트별로 파일들을 나누어 이를 개선할 수 있다. 초기에 HTML이 비어있어, 검색 엔진 최적화에 문제가 있다. 또 자바스크립트가 로드될 때까지 페이지가 비어 있기 때문에 그동안 흰 페이지가 나타날 수도 있다.
React, 서버, 클라이언트, JS
SSR에서 사용되는 개념이다. SSR은 사전렌더링을 통해 완성된 정적 페이지를 클라이언트에게 전달한 이후 클라이언트는 번들링된 자바스크립트 코드(리액트)를 받아와 전달받은 HTML코드와 자바스크립트 코드를 서로 매칭시키는 과정을 수행하는데, 이 과정을 Hydrate라고 한다. 전송받은 자바스크립트들이 이전에 보내진 HTML DOM 요소 위에서 한번 더 렌더링하게 되면서 각각 자리를 찾아가며 매칭되는 것이다. Hydrate이후 클릭과 같은 이벤트가 가능해진다.
마치 자바스크립트 코드들이 DOM 요소 위에 물을 채우듯 필요로 하던 요소들을 채운다 하여 Hydrate(수화)라는 용어를 쓴다.
server에서 한번 렌더링하고 client에서도 한번 더 렌더링하면 비효율적이 아닌가?
서버 단에서 pre-rendering한 document는 모든 자바스크립트 요소들이 빠진 굉장히 가벼운 상태이므로 클라이언트에게 빠른 로딩이 가능하여 사용자에게 빠르게 응답할 수 있다.
클라이언트 단에서 자바스크립트가 렌더링할 때, 단지 DOM 요소에 자바스크립트 속성을 매칭시킬 뿐이므로 실제 웹 페이지를 다시 그리는 과정까지는 하지 않는다.
TTV(Time to View)는 사용자가 브라우저의 내용을 볼 수 있는 시점. TTI(Time to Interact)는 사용자가 브라우저에서 인터렉션할 수 있는 시점 .
SSR: 사이트에 접속하면 서버에서 이미 만들어진 파일 받아옴(TTV)-> 서버에서 자바스크립트를 받아와 Hydrate 과정을 거친 이후 클릭 처리 가능(TTI)
CSR: 사이트 접속-> index파일 받아옴(텅 빈 파일이므로 안보임)-> index에 링크된 모든 로직이 있는 자바스크립트 받아옴-> 동적으로 html생성할 수 있는 로직이 담긴 js 파일을 받아옴(TTV, TTI 가능)
SSR을 쓰면 접속시 검색엔진에 유의미한 HTML 문서를 바로 받아올 수 있다.
더 이상 다운 받은 자바스크립트를 이용해 클라이언트에서 HTML 문서를 만드는 게 아니라
클라이언트에 보내주기 전에 이미 완성된 HTML 문서를 보내준다.
이를 NextJS에서는 Pre-rendering이라고 한다.
정적인 HTML 문서를 바로 받을 수 있어 SEO에 유리해진다.
다만 사용자가 HTML 문서만 다운 받은 뒤 클릭 등의 조작을 하더라도 반응할 수 있도록
기본적인 인터렉션을 위한 자바스크립트의 내용이 미니멀하게 HTML 문서에 포함된다.
그 다음으로 자바스크립트 다운로드가 완료되고 나서야 컴포넌트 변경 등의 인터렉션을 수행할 수 있다.
서버에 사전에 저장된 렌더트리의 html을 로드한다.(사전 렌더링)
이후 CSR 방식을 사용한다. 번들링된 자바스크립트 코드를 받아와 하이드레이트 과정을 거치면 이후 동적으로 렌더링이 가능하다.
next는 싱글페이지 애플리케이션의 단점과 서버사이드 렌더링의 단점을 해결해주는 프레임워크이다. 싱글페이지 애플리케이션의 단점에는 페이지를 불러올 때 모든 자바스크립트 파일을 한번에 불러오기 때문에 시간이 오래걸리는 것과 처음 HTML이 비어있기 때문에 검색 엔진에 최적화되어있지 않다는 것이 있고, 서버사이드 렌더링의 단점은 페이지를 이동하면 새로운 페이지를 요청하기 때문에 깜빡거리게 되고 서버에 부담을 준다는 단점이 있는데, next를 사용하면 이런 단점들을 해결할 수 있으며 싱글페이지 애플리케이션과 서버사이드 렌더링의 장점을 얻을 수 있다.