Presentational & Container Components (2)

seohyun Kang·2023년 4월 20일
0

React

목록 보기
6/9

Introduction

이전에 작성했던 Presentational & Container Component (1) 에 이어서 개발하면서 두 요소에 대해 이해한 부분을 추가적으로 작성하려고 합니다.

과거 글을 수정하지 않고 추가로 작성하는 것은 오늘 작성한 내용도 오류가 있을 것이고 추후 (3) 글을 작성하게 되면 단계적으로 이해한 부분과 알게된 부분을 비교해보기 위해서 입니다.

Presentational Component

Application의 UI를 담당하는 컴포넌트

Presentaional, Pure, Dumb Component 모두 Application에서 같은 역할을 수행하는 컴포넌트로 Props를 전달받아 UI를 그리는 역할을 합니다.

> Current Architecture

<Presentational>
	<Title />
    <Description />
    <Input />
    <Title />
    <Description />
	<List />
	<Button />
</Presentational>

과거에는 Presentational Component의 개념을 하나의 큰 View라고 생각했습니다. 문제는 이와 같이 코드를 작성하면 HTML의 View와 관련된 코드가 지나치게 길어져 가독성을 떨어뜨리는 문제가 발생합니다.

> Target Architecture

<Presentational A>
	<Title />
    <Description />
    <Input />
</Presentational A>
<Presentational B>
	<Title />
    <Description />
    <List />
    <Button />
</Presentational B>

이처럼 분리하면 View를 그리는 코드를 두 부분으로 분리하여 코드 가독성을 높일 수 있지만 사실상 재사용하지 못하는 컴포넌트를 만들게 되어 컴포넌트의 불필요한 Deps를 증가시킨다고 생각했기 때문에 위와 같은 코드 분리에 대해서 고민했습니다.

위와 같이 컴포넌트를 분리하고 개발자로 하여금 구조적으로 혼돈을 주지 않으려면 컴포넌트만으로는 어렵다는 생각이 들었습니다.

> After Architecture
<MainView>
	<Presentational A>
		<Title />
    	<Description />
   		<Input />
	</Presentational A>
	<Presentational B>
		<Title />
    	<Description />
    	<List />
    	<Button />
	</Presentational B>
</MainView>
views/
ㄴ MainView/
	ㄴ Presentational A.tsx
    ㄴ Presentational B.tsx
    ㄴ Title.tsx
    ㄴ Description.tsx
components/
ㄴ Common/
	ㄴ Button.tsx
    ㄴ Input.tsx

위와 같이 분리하면 재사용성이 없는 Presentational Component를 사용하더라도 유지보수 간의 복잡성을 낮출 수 있을 것으로 생각합니다.

Presentational A || B도 더 작은 단위로 분리할 수도 있지만, 어느 정도 수준이 적당한지 역시 고민해야할 것 같습니다.

Container Component

Application의 상태 (State)를 담당하는 컴포넌트

Presentational Component와 다르게 Container Component에 대해서는 고민의 영역이 명확했던 것 같습니다.

기능 단위로 구분한다.

앞서 이야기했지만 이전에는 Presentational Component가 하나의 큰 View라고 생각했기 때문에 전체 View의 상태를 관리하는 코드가 한 Container 안에 들어가게 되었고, 이는 Container Component의 가독성을 떨어뜨리는 계기가 되었습니다.

<Container>
	<Presentational>
    	<Title />
        <Description />
        <Input />
        <List />
        <Title />
        <Description />
        <Button />
    </Presentational>
</Container>

이 코드에서 Container는 Presentational에 전달하는 모든 State, Event handler 등을 Props로 전달해야 했습니다.

<Container A>
	<Title />
    <Description />
</Container A>
<Container B>
	<Presentaional>
    	<Input />
        <List />
    </Presentaional>
</Container B>
<Container C>
	<Title />
    <Description />
	<Presentaional>
    	 <Button />
    </Presentaional>
</Container C>

Container Component를 구분하는 기준은 다음과 같습니다.

  1. 데이터를 로드하거나 상태를 업데이트하는 로직이 있는 컴포넌트
  2. Redux나 MobX와 같은 상태 관리 라이브러리와 연동하는 컴포넌트
  3. 다른 컴포넌트를 렌더링하는 것이 주된 역할이 아닌, Presentational Component를 관리하는 컴포넌트

위와 같이 비즈니스 로직, 상태 관리, Presentational Component 관리 등을 기준으로 Container Component를 생성하여 코드를 분리하고 가독성을 높이고 및 유지보수를 용이하게 만들 수 있습니다.

Props Drilling

이전 글에서 Props Drilling이 발생한다고 마지막에 작성했습니다. 지금에 와서 생각하면 한 Container 안에 속한 컴포넌트에는 Props를 전달하는게 맞습니다. Props를 Container에서 Presentationl로 전달하면서 두 컴포넌트 간의 관계가 명확해지게 됩니다.

오히려, Container A의 상태값을 Container B에 있는 Presentational Component가 직접 가져오게 되면 해당 상태값의 출처를 확인할 수가 없어 유지보수를 어렵게 만듭니다.

결론적으로

개발업무를 진행하면서 Presentational & Container Component의 성질이나 특징을 좀 더 이해하게 되었고 이전과 같이 막연한 기준이 아니라 컴포넌트를 사용하는데 있어서 기준점을 가지게 된 것은 다행이라고 생각합니다.

다만, 이와 같은 구성으로 코드를 작성하면서도 때때로 이렇게 코드를 분리하거나 묶는게 맞는지 의문이 드는 경우가 종종 있습니다. 기초적인 가이드를 가지고 개발을 하면서도 개발은 왕도가 없기에 계속해서 문제와 의문이 생기고 이를 더 나은 방법을 찾아서 해결하는게 앞으로 나아갈 길인 것 같습니다.

0개의 댓글