[Week 2-2] Logic First, React Later
4-1) ‘React 다운 코드’ 다시 생각하기
이번 챌린지에서 배운 내용들을 생각해 보자.
[1차] - 데이터 / 액션 / 계산 구분 및 분리
[2차] - 비즈니스 로직 / UI 로직 구분 및 분리
[3차] - SOLID 원칙과 React 컴포넌트 패턴
공통적으로 챌린지의 주제처럼 비즈니스 로직을 이해하고 추상화 원칙에 따라 좋은 컴포넌트 작성을 통해 개발 생산성을 높이려고 노력을 해왔다.
React는 렌더러입니다. 화면을 그리는 역할에 집중하도록 하는 것이 좋습니다.
이제 다시 원점으로 돌아와 React에 대해 다시 한번 고민해 보면 무엇을 잘하고 어떤 일을 맡겼을 때 원하는 대로 결과물을 만들 수 있는지 알고 있어야 한다.
그래서 DECLARATIVE가 뭔데?
React, Vue, Angular와 같은 "선언적 UI", 다들 쓰길래 우리도 도입한 거긴 한데... "선언적 UI"가 대체 뭐길래 세상을 이토록 바꿔놓았을까요? 그리고 "컴포넌트 기반 설계", "관심사의 분리", "single-source-of-truth" 등 알쏭달쏭한 키워드들은 대체 왜 생겨났을까요?
- 원지혁
https://www.youtube.com/watch?v=r7M9B_dEbCI
4-2) Core에서 Adaptor로, 다시 React로
2019년에 작성된 글이지만 지금 보더라도 얻을 수 있는 게 충분하다고 소개하며 추천해 주셨다.
https://www.rinae.dev/posts/ui-as-an-afterthought-kr
“context(컨텍스트), hooks(훅), suspense(서스펜스)같은 리액트의 새 기능이 추가되었는데 앞으로 우리가 (웹) 앱을 만드는데 많은 영향을 미칠까요? 리액트 팀에서 Redux(리덕스)나 MobX(몹엑스)가 쓸모없어지는 새로운 상태 관리 라이브러리를 만들까요?”
위 질문으로 시작으로 글이 시작된다. 챌린지 3차에서 알아보았듯이 어떤 도구를 사용할지는 각각의 상황과 환경에 맞게 판단해야 한다고 설명한다. 즉 많은 라이브러리를 아는 것보다 적재적소에 잘 적용할 수 있어야 한다는 것이다.
우리는 웹 애플리케이션을 다른 방향에서부터 만들어야 하고, 먼저 사용자가 시스템과 어떻게 상호작용할지 코드로 작성하는 일부터 시작해야 합니다. 앱을 사용하면서 어떤 과정을 거치게 되는지, 또 어떤 정보를 필요로 할지, 어떤 정보를 서버로 전송할지 등 달리 말하면 해결해야 하는 문제의 도메인(domain)을 모델링하는 작업부터 시작하는 겁니다.
일반적으로 아래와 같은 순서로 React 애플리케이션을 구현하게 된다.
JSX로 HTML element 작성 -> 각각의 element에 기능 로직 작성
하지만 반대로 뒤집어서 구현을 한다고 생각해 보면 어떻게 될까
1. 비즈니스에 필요한 element를 정의
2. element가 행동할 수 있는 경우를 수집하고 기능 구현
3. UI 작성
위와 같은 순서로 작업했을 때 얻을 수 있는 장점들이 있다.
1. 비즈니스 로직에 대한 SSOT(Single Source Of Truth, 단일 진실 공급원) 달성
-> 프로덕트를 이루고 있는 코드가 SSOT 달성을 위한 자격이 되므로 비즈니스 로직을 코드로 표현하려면 무엇이 필요한지 고민해야 한다.
2. 새로운 팀원에게 빠른 온보딩이 가능
-> 새로운 팀원 혹은 기존 팀원이 로직을 파악하는데 도움이 된다.
3. 테스트를 작성하기 쉽다
-> 프론트 엔드 테스트의 경우 대상이 UI가 아닌 계산에 가까운 코드라면 테스트 코드를 작성하기 수월해진다.
먼저, 웹 애플리케이션이 아니라 CLI를 만들듯이 상태와 스토어, 프로세스를 설계하세요.
비지니스 프로세스를 함수 형태로 직접 호출하는 것만큼 단순한 게 없습니다.
대부분의 컴포넌트는 상태가 없는 컴포넌트(dumb)가 됩니다.
UI는 그저 나중에 고려할 사항입니다(UI is just an afterthought).
이벤트 기반 웹뷰 프레임워크 설계와 플러그인 생태계 만들기
- 원지혁
https://www.youtube.com/watch?v=pEPOGDPDU-U
올해 FEConf에서 발표한 위 영상을 요약하자면 다음과 같다.
1. 화면 전환이나 히스토리 관리를 위해 당근에서 KarrotFrame이라는 라이브러리를 만들었다.
2. 초기 버전에선 react-router와 결합하는 형태로 설계되었다.
3. History API와 react state가 한 벌로 존재하기 때문에 상태 동기화 과정에서 오류가 잦았다.
4. 이를 개선한 다음 버전에선 특정 프레임워크에 종속되지 않는 것을 목표로 잡았다.
여기서도 알 수 있듯이 종합하자면 제품 개발 과정에서 먼저 Core 로직을 구성하고 이를 UI와 분리하여 개발을 하고, 이후 UI를 작성하며 마지막으로 Core 로직과 UI를 효과적으로 연결하여 완성하는 방식이 여러 면에서 장점을 갖고 있음을 알 수 있다.
4-3) [실전 스킬 4] 난잡한 코드베이스를 위한 추상화 벽 시공법
https://velog.io/@eunbinn/modularizing-react-apps
종종 사람들은 애플리케이션을 작동시키기 위해 여러 가지를 리액트 컴포넌트나 훅에 짜깁기하는 경우가 많습니다. 애플리케이션의 규모가 작거나 비즈니스 로직이 거의 없는 경우엔 이러한 덜 체계적인 구조는 큰 문제가 되지 않습니다. 하지만 대부분의 경우 더 많은 비즈니스 로직이 프론트엔드로 이동함에 따라 이런 짜깁기된 컴포넌트는 문제를 드러냅니다.
'UI는 좀 이따 생각해 봅시다.'와 같은 맥락에서 React를 바라보고 있다. 순수하게 React로만 이루어진 애플리케이션을 만드는 것보다 React가 잘하는 부분인 UI 렌더링에 전념할 수 있도록 하자는 것이다.
하나의 컴포넌트에서 너무 많은 작업들을 하고 있기 때문에 가독성이 현저히 낮아진다.
단일 컴포넌트 애플리케이션에서 추출한 여러 컴포넌트가 있고, 순수한 프레젠테이셔널 컴포넌트와 다른 컴포넌트의 상태를 관리할 수 있는 재사용 가능한 훅이 있습니다. 유일한 문제는 훅에서 사이드이펙트와 상태 관리를 제외한 일부 로직은 상태 관리보다는 순수한 계산에 해당한다는 것입니다.
또한, 이러한 계층들이 갖는 이점을 아래와 같이 설명하고 있다.
- 유지보수성 향상: 컴포넌트를 여러 부분으로 분리하면 코드의 특정 부분에서 결함을 찾아 수정하기가 더욱 쉬워집니다. 따라서 시간을 절약하고 변경 시 새로운 버그가 발생할 위험도 줄일 수 있습니다.
- 모듈성 향상: 계층 구조가 더 모듈화 되어 코드를 재사용하고 새로운 기능을 구축하기가 더 쉬워집니다. 예를 들어 뷰는 각 계층에서 더 쉽게 구성할 수 있습니다.
- 가독성 향상: 코드의 논리를 이해하고 따르기가 훨씬 쉬워집니다. 이는 코드를 읽고 작업하는 다른 개발자에게 특히 유용할 수 있습니다. 이것이 바로 코드베이스 변경의 핵심입니다.
- 확장성 향상: 각 개별 모듈의 복잡성이 감소하면 전체 시스템에 영향을 주지 않고 새로운 기능을 추가하거나 변경하기가 더 쉬워지므로 애플리케이션의 확장성이 향상되는 경우가 많습니다. 이는 시간이 지남에 따라 발전할 것으로 예상되는 대규모의 복잡한 애플리케이션에 특히 중요할 수 있습니다.
- 다른 기술 스택으로의 마이그레이션: 필요한 경우 (대부분의 프로젝트에서는 거의 불가능하지만) 기본 모델과 로직을 변경하지 않고 뷰 계층을 교체할 수 있습니다. 도메인 로직이 순수 자바스크립트(또는 타입스크립트) 코드로 캡슐화되어 있고 뷰의 존재를 인식하지 못하기 때문입니다.
https://velog.io/@eunbinn/series/FE-%EB%B2%88%EC%97%AD
📝 오늘의 3줄 요약
1. 애플리케이션을 작업할 때 비즈니스 로직을 먼저 고려하고 파악하자.
2. 약은 약사에게 UI 랜더링은 React에게
3. 여러 가지 경우를 고려하여 좋은 코드를 짜도록 하자.