This month I Learned - 22년 9월
(내용 정리에 생각을 덧붙일 경우 🤔
이모지를 첨부합니다.)
Development #
어댑터 디자인패턴을 이용한 레거시 API 호출 마이그레이션 #
- 모놀리식에서 마이크로 아키텍처로 마이그레이션 하는 상황
- BFF에서 기존 레거시 api를 어댑터로 연결하여 프론트에서 단일 엔드포인트(BFF)와 상호작용 할 수 있도록 지원
선언적 리액트, 제어 역전 #
- 선언적 프로그래밍은 두 가지 뜻으로 통용되고 있따.
- 프로그램이 어떤 방법으로 해야하는지를 나타내기 보다 무엇과 같은지를 설명하는 경우
- 프로그램이 함수형 언어, 논리형 언어 혹은 제한형 언어로 쓰인 경우
- UI 관점에서 어떤 것을 의미하나?
- 명령형 방식에서 UI를 렌더링 하는 경우, 돔을 어떤 순서로 조작할지에 대해 하나씩 순차적으로 알려준다.
- 반면, 선언형 방식은 렌더링이 끝난 후 보기를 원하는 최종 결과물을 선언하고, 해당 결과물을 렌더링하는 것은 UI 라이브러리의 책임으로 넘긴다. → 리액트의 렌더링 방식
- 제어 역전
- 리액트에게 내가 그리고 싶은 UI 요소들의 묶음을 선언해서 전달하면, 리액트는 이 선언을 화면에 그리기 위한 작업을 수행한다.
- 이 과정을 통해 자연스럽게 DOM에 화면을 렌더할 책임이 개발자에서 리액트로 넘어가므로, 제어가 역전되었다고 볼 수 있다.
- 좋은 런타임은 직면한 문제와 일치하는 근본적인 추상화를 제공해 준다.
왜 Recoil을 써야 하는가? #
- 상태 관리에 대한 정의
- 상태? 애플리케이션의 동작 방식을 설명하는 모든 데이터
- 상태관리는 시간이 지남에 따라 상태가 변경되는 방식이다.
- 상태 관리에 필요한 기능 - 최초 값 설정, 현재 값 읽기, 값 업데이트
- recoil은 왜 필요한가?
- 리액트의 내장 상태관리 기능의 한계점 극복
- 최대한 리액트스러운 api 유지
- 사용하기 위한 부속 라이브러리 최소화
- 리액트 상태 관리 로직의 한계점
- 컴포넌트 상태를 공유하기 위해선 공통되는 부모 컴포넌트까지 올라가야하는데, 심할 경우 최상단까지 올라가야하는 문제 - prop drilling
- context api는 확정되지 않은 수의 값을 저장하는데 적합하지 않으며, 최적화 관점에서 한계점이 명확함
- context api는 상태 관리라기 보다는 개념상 의존성 주입에 가깝다.
- recoil의 접근 방법
- recoil은 react tree에 직교되는 형태로 존재하는 방향 그래프로 구성되어 있다.
- 상태 변경은 이 그래프를 따라 리액트 컴포넌트로 흘러들어간다.
- 다양한 장점들이 있지만, 가장 큰 장점으로 component쪽의 로직을 건드리지 않고 상태 데이터를 단독으로 변경할 수 있다.
- redux는 React-redux 와 같은 중간다리 역할을 하는 라이브러리가 필요했음.
- recoil의 철학
- 보일러 플레이트가 적은 api면서 react의 로컬 상태와 유사한 간단한 인터페이스
- concurrent mode와 호환
- 코드 상호간의 낮은 결합도를 통해 코드 스플리팅 용이성 확보
- 파생 데이터를 사용함으로써 데이터를 사용하는 컴포넌트에서 임의로 데이터를 바꾸는 로직을 가져가지 않아도 된다. → selector
- 예를 들어 A박스와 B박스가 겹쳐져 있는 상태(isOverlapped)를 확인하기 위해 useMemo나 useEffect 내에서 수행하던 로직을 컴포넌트 외부의 selector에서 수행 가능함.
- 코어 컨셉
- Flexible shared state : 유연하게 상태 관리 가능
- 공통적으로 필요한 데이터를 어떻게 저장할 것인가?
- contextApi를 사용하면 Dynamic하게 구성할 수 없음 + 트리상 루트와 리프간의 Coupling 발생
- Provider가 추가될 때마다 Tree는 다시 reconciling을 해줘야 하는 이슈.
🤔
Dynamic하게 구성한다고 하는게 뭔지 잘 모르겠음.
- react의 로컬 component state와 동일하게 batching과 같은 작업들이 모두 라이브러리 내부에서 처리된다.
- Derived data and queries : 파생 데이터 생성 용이
- 파생 데이터 : 상태와 관련 있거나, 상태로부터 만들어진 것
- 상호 의존적인 state를 만들 필요가 없다. (두 개의 atom을 참고한 또 하나의 atom)
- pure function으로 atom 데이터를 사용할 수 있도록 해준다.
- App-wide state observation : 애플리케이션 단의 상태 Observing 가능
- Flexible shared state : 유연하게 상태 관리 가능
- 왜 Recoil이 괜찮은 선택일까?
- 낮은 진입장벽, 간단한 api
- react api와 굉장히 유사하여 대체하기 쉽다.
- 비동기 데이터 처리가 용이함.
- atomFamily, selectorFamily를 이용하여 국소적으로 사용하는 상태를 생성할 수 있음
- atomFamily - writeable한 recoilState atom을 반환하는 함수를 반환한다.
- atom의 모음집으로 저장한다. 기본적으로 리코일 내부적으로 캐싱과 같은 최적화를 진행해줌.
- atomEffects를 이용해 변화하는 값을 추적할 수 있음
- 낮은 진입장벽, 간단한 api
- QnA
- flux패턴에서 Mvc로 다시 돌아가는게 아닌가?
- mvc에서 flux로 넘어가게된 이유는 데이터 관계에 있어 화면과 모델간의 상호 의존성이 발생
- recoil 자체는 Mvc라고 보기 어렵다고 생각한다. 리코일은 화면과는 분리가 되어 있음.
- flux의 장점을 버릴 이유가 있나? state가 많아진다면 관리하기 어려워질수도?
- flux패턴에서 Mvc로 다시 돌아가는게 아닌가?
Mocking으로 생산성까지 챙기는 FE 개발 #
- msw는 api mocking 라이브러리로, 서버로의 네트워크 요청을 가로채서 모의 응답을 보내주는 역할을 한다.
- mocking 서버를 구축하지 않아도 api를 네트워크 수준에서 모킹할 수 있음.
- 서비스워커란?
- 웹 애플리케이션의 메인 스레드와 분리된 별도의 백그라운드 스레드에서 실행시킬 수 있는 기술 중 하나.
- 애플리케이션의 ui block없이 연산을 처리할 수 있다.
- msw 동작 원리
- 먼저 브라우저에 서비스 워커를 설치한다.
- 이후에는 브라우저에서 실제 이루어지는 요청을 서비스 워커가 가로채게 됨.
- 서비스 워커에서 실제 요청을 복사해 msw에게 해당 요청과 일치하는 모의 응답을 제공받고 이를 브라우저에게 그대로 전달한다.
Application State Management with React #
- 상태관리를 어렵게 만드는 원인 중 하나는 우리가 종종 문제에 대한 솔루션을 과도하게 엔지니어링 한다는 점.
- 리덕스가 성공 이유 중 하나는 react-redux가 Prop-drilling 문제를 해결했기 때문.
- 하지만 많은 개발자들이 그들이 사용하는 모든 상태를 리덕스에 넣는다. 전역 애플리케이션 상태뿐만 아니라 지역상태까지 말이다.
- 이로인해 리듀서, 액션, 디스패치 호출과의 상호작용과 관련되어 많은 파일을 열고 추적해야 한다.
- 간단한 경우 useState의 지역상태로도 상태관리하기 충분하다.
- 상태 공유의 경우 Lifting State UP. 부모로 상태를 올려서 해결가능함.
- propDrilling의 경우는 컴포넌트 조합을 사용하거나 context 사용.
- 서버 캐시 vs UI 상태
- 모든 유형의 상태는 다음 두 종류 중 하나에 속할 수 있다.
- 서버 캐시 - 실제로 서버에 저장되고 빠른 액세스를 위해 클라이언트에 저장하는 상태
- UI 상태 - 앱의 대화형 부분(isOpen 등)을 제어하기 위한 UI에서만 유용한 상태
- 서버 캐시는 본질적으로 UI 상태와 다른 문제를 가지고 있으므로 다르게 관리해야 한다.
- 상태가 아니라 상태의 캐싱이다.
- useContext, useState등을 사용해 관리할 수 있지만 캐싱은 어려운 문제이므로 React-query 사용하는게 현명함.
- 모든 유형의 상태는 다음 두 종류 중 하나에 속할 수 있다.
Javascript Colocation #
- 만약 코드에 대한 주석을 코드가 표현되는 곳이 아닌 다른곳에 위치시킨다면 어떤 문제가 있을까
- 유지보수성 - 코드를 업데이트 할 때 주석은 업데이트 하지 않아 싱크가 깨질 수 있음.
- 적용성 - 다른 사람들이 src/의 코드를 살펴보고 docs/ 의 주석을 놓치거나 업데이트하지 않을 것
- 쉬운 사용성 - 한 장소로부터 다음으로의 컨텍스트 스위칭은 장애물이 된다.
- 예시
- css in js
- test - 좀 더 유지가능한 코드가 가능하도록 돕기 위해 그들이 테스트하는 파일들의 그룹 혹은 test file을 동일한 위치에 배치해야 한다.
- state - 상태가 사용되어지는 UI로부터 상태가 끊어지거나 직접적이지 않을 수록 유지보수 하기는 힘들어진다. 상태를 적절히 위치시키는 것은 유지보수보다 큰 이점을 가진다. 어플리케이션의 성능 또한 증가시킴. 컴포넌트 트리의 한쪽에서 상태의 변환느 트리의 꼭대기에서 상태가 변하는 것보다 적은 컴포넌트를 리렌더링한다. 상태를 지역화하라.
- 원칙 : 코드를 사용 가능성이 있는 곳에 가깝게 위치시켜라.
이번달은 열심히 안했다..