나는 리액트를 어떻게 설계할 것인가?

양다혜·2022년 2월 19일
18

React

목록 보기
1/1
post-thumbnail

리액트를 공부한지 약 2~3개월이 되었는데, 이전에는 단순히 CRA(create-react-app)로 리액트 프로젝트를 생성하고 책이나 강의를 통해 따라서 구현하곤 했다. 그런데 팀이 생기고 협업을 진행하다보니, 프로젝트를 진행할 때 어떤 패턴을 사용할 것인지, 폴더 구조는 어떻게 이룰 것인지에 대한 생각을 하게 되었다.

혼자서 리액트를 공부하거나 클론 앱 등을 만들 때는 단순히 CRA로 제작이 가능하고 전체 구조를 확인하기 편하지만, 실제 실무에서는 사이트 규모에 따라 엄청나게 많은 컴포넌트로 구성이 되어있을 것이고 이후에 내가 투입 되어 이를 다 파악해야 하는 상황도 있을 것이다.

최초 설계 시 의도와 계획, 가이드가 명확하지 않다면 이후 실무처리 과정에서 리액트 구성요소들은 엄청나게 비대하고 복잡해지게 될 것이다. 또한, 정리를 해두지 않으면 이후에 재사용 가능한 컴포넌트가 있음에도 불구하고 활용을 못하는 사태가 벌어질 수 있다.

이러한 문제들을 해결하기 위해서는 프로젝트 구축 전 충분한 고민과 기준을 가지고 설계를 계획하는 것이 중요할 것이다. 또한 내 후임자가 왔을 때, 내 설계 기준을 충분히 이해할 수 있도록 하고, 같이 작업하는 사람이 여럿일 경우 기준을 공유할 수 있도록 가이드가 있어야 할 것이다.

따라서 리액트 컴포넌트와 폴더 구조에는 어떤 것이 있는지 알아보고자 한다.

리액트 컴포넌트 패턴

Presentation - Container Component

Presentation-Container Component 패턴은 과거에 자주 언급되고 활용되었던 패턴이다. Container Component에서 데이터를 처리하고, Presentation Component에서 데이터를 출력하는 형태로, UI와 로직을 분리하여 관리하는 패턴이다. 이유는 하나의 컴포넌트에 api 호출, 이벤트 함수, 로직 등 모든 것이 담겨있으면 파일 하나하나가 엄청 커지고, 유지보수 또한 힘들어질 수 있기 때문이다. 하지만 처음 이 패턴을 소개한 Dan Abramov는 2019년을 기준으로 현재는 이 패턴을 사용하지 말라고 언급하고 있다. Hook 이 등장하며 임의의 분리없이 똑같은 일을 할 수 있기 때문이다.

💡 Update from 2019: I wrote this article a long time ago and my views have since evolved. In particular, I don’t suggest splitting your components like this anymore. If you find it natural in your codebase, this pattern can be handy. But I’ve seen it enforced without any necessity and with almost dogmatic fervor far too many times. The main reason I found it useful was because it let me separate complex stateful logic from other aspects of the component. [Hooks](https://reactjs.org/docs/hooks-custom.html) let me do the same thing without an arbitrary division. This text is left intact for historical reasons but don’t take it too seriously.

Custom Hooks

Custom hooks 는 위의 Presentation-Container Component 패턴에서 로직을 hooks로 관리하는 것이다. hooks로 로직을 관리하면 UI 재사용, 로직 재사용까지 가능해진다.

custom hooks 는 로직이 렌더링과 분리되어 있어 이 둘을 연결하는 것은 사용자의 몫이다. 컴포넌트를 올바르게 구현하려면 컴포넌트의 동작 방식에 대한 깊은 이해가 필요하다.

atomic 디자인

아토믹 디자인은 원자, 분자, 유기체, 템플릿, 페이지로 효과적인 인터페이스 시스템을 만드는 것이다. 웹 사이트의 구성 블록이 HTML 요소들이며 이 요소들은 원자로 볼 수 있다. 원자가 결합되어 분자가 되는 것처럼 HTML 요소들은 결합되어 복잡한 페이지를 형성한다.

원자(Atoms) - 버튼, 제목, 텍스트 입력 필드(모든 컴포넌트들의 기초가 되는 블록, 더 이상 분해될 수 없는 필수 요소)

분자(Molecules) - 2개 이상의 원자로 구성, 하나의 단위로 함께 동작하는 UI 컴포넌트의 단순한 그룹

유기체(Organisms) - 분자, 원자 또는 다른 유기체의 그룹으로 구성된 비교적 복잡한 그룹, 이 유기체들은 인터페이스의 개별적인 영역을 형성

템플릿(Templates) - 컴포넌트들을 배치하고 설계의 구조를 보여줌

페이지(Pages) - 실제 컨텐츠들을 배치한 UI를 보여줌, 템플릿의 구체화된 인스턴스

아토믹 구조는 UI 재사용성이 매우 뛰어나다. 하지만 디자인 시스템 구축을 위한 초기 비용이 많이 들고, 로직과 State들을 page 단위에서 props로 내려줘야하는 단점이 있다.

리액트 폴더 구조

리액트는 다양한 폴더 구조가 있다.

  • components = 컴포넌트들
  • pages = 페이지들
  • hooks = hooks들
  • style = 스타일
  • assets = 이미지, 아이콘 등 정적 파일
  • utils = 유틸 함수들
  • api = api 목록들
  • types = type들(in ts+react)
  • store = 전역 상태

자주 사용되는 폴더들은 다음과 같다. 폴더 구조는 리액트 공식문서에서 제시된 구조 두 가지를 예로 살펴보자.

파일의 기능이나 라우트에 의한 분류

common/
  Avatar.js
  Avatar.css
  APIUtils.js
  APIUtils.test.js
feed/
  index.js
  Feed.js
  Feed.css
  FeedStory.js
  FeedStory.test.js
  FeedAPI.js
profile/
  index.js
  Profile.js
  ProfileHeader.js
  ProfileHeader.css
  ProfileAPI.js

css, js, 테스트 파일을 기능이나 라우트로 분류된 폴더에 같이 두는 방법이다.

파일 유형에 의한 분류

api/
  APIUtils.js
  APIUtils.test.js
  ProfileAPI.js
  UserAPI.js
components/
  Avatar.js
  Avatar.css
  Feed.js
  Feed.css
  FeedStory.js
  FeedStory.test.js
  Profile.js
  ProfileHeader.js
  ProfileHeader.css

비슷한 파일끼리 묶어주는 방법이다.

또한, 폴더 구조를 정할 때 유의할 점은 너무 많은 중첩을 피하는 것이다.

이렇게 다양한 리액트의 컴포넌트 패턴, 폴더 구조들을 살펴보았는데 그러면 컴포넌트 패턴, 폴더 구조는 어떻게 설계해야할까?

리액트는 수많은 컴포넌트로 이루어져있기 때문에 컴포넌트를 잘 설계하는 것이 리액트 프로젝트를 잘 설계하는 것에 큰 비중을 차지한다.

  • 확장성, 재사용성 있는 코드를 만들어야한다. 의존성이 짙고 목적성이 사라진 코드는 컴포넌트의 특징을 무시한 채 재사용성과 범용성이 부족한 채 작업된 것이라고 할 수 있다.
  • 코드를 분리하고 단일 책임을 가지는 컴포넌트를 생성해야 한다. 재사용성과 범용성을 가지기 위해서는 관심사에 따라 딱 한가지의 역할만 수행시키기를 권장한다.(ex. 단일 책임 원칙) 순수함수의 특성과 같이 동일한 props를 받으면 같은 JSX를 리턴할 수 있어야 한다.
  • 외부에 제어를 위임 시키는 것을 고려해야 한다. 제어를 외부에 위임할수록 코드에 대한 이해 난이도가 높아지고, 가독성이 떨어질 수 있다.

각 컴포넌트 패턴과 폴더 구조의 장단점을 고려하여 해당 프로젝트에 알맞은 패턴, 구조를 계획하는 것은 정말 중요할 것이다.

profile
아는 것을 잘 설명할 수 있는 개발자되기👩🏻‍💻

1개의 댓글

comment-user-thumbnail
2023년 2월 11일

너무 좋은 글입니다. 감사해요!

답글 달기