회사에서 Presentational&container 패턴을 적용하게 되어, 정확한 개념을 공부하고, 공부하면서 알게된 사실을 정리한 글입니다.
Presentational component
Container component
- 어떠한 동작을 할 것인가에 대해 책임진다.
- statefull : 주로 상태를 가지고 있다.
- side effects를 만들 수 있다.
- 절대로 DOM 마크업 구조나 스타일을 가져서는 안된다.
코드예시
이 패턴의 창시자인 Dan Abramov
님이 2019년에 더 이상 이렇게 구성 요소를 분할하지 않는 것이 좋다는 말을 남기셨다. 잘 쓰고 있어서 찬양하려고 글을 쓰는 중이었는데..?
코드베이스에서 자연스럽다면 이 패턴이 유용할 수도 있지만, Hooks를 사용하면 임의의 분할 없이 동일한 작업(Hook은 로직과 표현의 분리를 가능하게 한다)을 수행할 수 있고
, 필요에 의해서가 아닌 맹목적으로 사용하는 경우를 많이봤기 때문이라고 한다.
하지만 2021년에도 해당패턴이 중요한 이유를 설명한 글을 찾았다!
컴포넌트 안에서 데이터를 처리하는 로직을 사용하는 경우 컴포넌트의 재사용성이 떨어지는 것은 사실이다. 특히 특정 라이브러리와 프로그램의 아키텍처에 강하게 의존성이 생긴다. 예를 들어 react-intl 라이브러리에서 제공하는 hook을 쓰다가, react-i18n으로 라이브러리를 바꾼다면? 라이브러리리에서 제공하는 로직을 사용하는 모든 컴포넌트를 찾아 수정해야할 것이다.
presentatation 계층의 컴포넌트라면 스타일이나 Bootstrap, Material UI와 같은 라이브러리와 연결하는 것이 좋다.
Presentainal Component
1. html, css 및 기타 프리젠테이션 구성요소만 사용할 수 있다.
2. 다른 App에서도 사용할 수 있어야 한다. (App의 설계나 framework에 종속되지 않음)
3. style 관련된 hook만 포함해야 한다.
4. 고차 컴포넌트로 래핑되지 않는다. 예를 들어 리덕스를 사용한다면, 더 높은 순서의 연결 컴포넌트가 컨테이너 컴포넌트에 추가되어야 한다.
5. 컴포넌트의 시각적 특성을 변경하는 props를 종종 허용한다.
6. 완전히 다른 스타일 시트를 로드하는 props를 종종 허용한다.
Container Component
1. html이나 style에 관한 것은 포함하지 않는다.
2. presentation component나 다른 container component를 사용할 수 있다.
3. 로직은 hook file에 들어간다. (reacdt-hooks-testing-library를 사용해 test하기 위함)
4. Props를 받을 수 있다.
5. Context를 사용하고, side effect를 만들고, db에 CRUD 작업을 요청할 수 있다.
6. CRUD 작업이 성공했을 때 UI에 즉시 반영하고, 실패했을 때는 UI를 롤백한다.
7. 항상 cotnainer 구성 요소에서 테스트 ID를 선언하고 구성 요소에 테스트 ID를 전달한다.
회사에서도 함수형 컴포넌트와 Hook을 사용했고, container도 unstated-next가 제공하는 hook을 이용해 container를 만들었다.
개념적으로 view와 데이터 관련 로직을 분리했지만, container component가 아닌 context에 관련 로직을 작성했다.
그렇게 함으로써 컴포넌트의 재사용성이 높아졌고, 불필요한 컴포넌트의 수를 줄일 수 있었다. 예를 들어 영화목록 페이지라고 하면
Movie Page > Movie Table 컴포넌트 = 데이터 로직 + table 컴포넌트 로직 으로 구성했다면
Movie Page + Container --props--> table 컴포넌트 로 구성을 할 수 있다.
그리고 구조적으로도 파악하기 쉽고 presentatonal component가 깔끔해졌다.
Container가 복잡해지는 문제가 있지만 관심사에 따라 Container를 분리하면 될 것 같다.
이번 내용을 정리하면서 Presentational - container pattern의 개념과 등장배경에 대해 알 수 있었고, Hook과 ContextAPI에 대해 더 공부해야겠다고 느꼈다.
reference