리액트 폴더 구조 우수 사례 - Container&Presenter 패턴

2025. 8. 3. 00:01·웹/React
반응형

프로젝트 폴더 관리 방법론 중 하나인 Container&Presenter 패턴에 대해 소개합니다.

상태 관리 이전의 패턴으로 현재는 권장하지 않습니다.

 

오래된 리액트 프로젝트(특히 클래스기반)에서 자주 찾아볼 수 있습니다.

기존의 프로젝트를 유지보수하는데 발견하였다면 이해하는데 도움이 되기를 바랍니다.

 

블로그에 개발 관련 글을 작성중이니 많은 관심 부탁드립니다.

1. Container&Presenter란?

  • Presenter: 데이터가 어떻게 사용자에게 보여질지에 대해서 다루는 컴포넌트
  • Container: 어떤 데이터가 보여질지 다루는 컴포넌트

Container&Presenter 패턴은 MVC 패턴에서 영감을 받았습니다.

당시 골치였던 Props Drilling 현상을 조금 이해하기 쉽게 하기위해 사용했습니다.

 

Redux, Zustand 같은 상태관리 라이브러리가 Props Drilling 현상을 해결했다면,

Container&Presenter는 Props Drilling과 공존을 선택했다고 생각하면 됩니다.

ㄴcomponents
    ㄴcontainer
        ㄴPostContainer
        ㄴCommentContainer
    ㄴpresenter
        ㄴPost
        ㄴCommnet
ㄴservices
   ㄴapi

        ㄴfetchPost
        ㄴfetchCommnet

 

패턴이 적용된 폴더를 구조화하면 다음과 같이 나옵니다. 각각의 역할은 MVC패턴으로 아래와 같이 바인딩됩니다.

  • Model: api 폴더
  • View: pontainer 폴더
  • Controller: presenter 폴더

1-1 API - Model

데이터의 시점에서 Model에 해당하고 API 호출을 담당합니다.

자료형은 백엔드에서 넘겨준 데이터 그대로 사용합니다.

export default async function fetchPost() {
	return fetch(host)
}

1-2 Container - View

API 호출과 데이터의 정제를 담당합니다. 데이터를 사용하지 않고 props를 통해 넘겨주는 역할을 합니다.

데이터의 호출과 정제를 Container에서 담당하므로 코드 수정 도중 데이터의 출처를 찾는다면 containers 폴더에서 탐색하면 되죠.

 

Container&Presenter 패턴에서의 데이터 흐름은 아래와 같습니다.

Container -> Container -> Container -> ...... -> Presenter

 

Props Drilling이 해결된건 아니지만 API 호출과 정제를 Container에게 위임함으로써 대응했습니다.

export default async function PostContainer() {
  const posts = await fetchPost()
  const comments = await fetchComment()
    
  return (
    <div>
      {
        Post.map((post) => {
          <PostPresenter 
            title = {post.title}
            description = {post.description}
            comments = {comments.filter((comment) => comment.postId === post.id)
          />
        })
      }
    </div>
  )
}
반응형

1-3 Presenter

Presenter는 반드시 Props를 통해 데이터를 받습니다.

패턴이 올바르게 적용되었다면 절대로 추가적인 데이터가 생성되어서는 안됩니다.

 

Container에서 API들을 조합하고 데이터를 정제해서 Presenter에게 넘겨줍니다.

Presenter는 받은 데이터를 화면에 표현하는 역할만 수행합니다.

export default function PostPresenter({ title, description, comments }) {
  return (
    <div>
      <h1>{ title }</h1>
      <div>
        { descriptoin }
      </div>
      <div>
        {
          comments.map((comment) => {
            <p>{ comment }</p>
          })
        }
      </div>
    </div>
  )
}

마치며...

Container&Presenter 패턴에 대해 알아보았습니다.

Props Drilling을 해결하기 위해 상태 관리 라이브러리가 탄생하기전, 선배 개발자님들의 고충과 공존을 선택한 우아한 패턴입니다.

 

현재는 사용할필요 없지만 패턴에 담긴 철학과 아이디어는 개발도중 한번씩 적용할 일이 있을지도 모릅니다.

물론... 그것보단 레거시 프로젝트를 유지보수하면서 만날 일이 더 많겠지만요.

추천 포스트

 

리액트 폴더 구조 우수 사례 - 아토믹 패턴

프로젝트 폴더 관리 방법론 중 하나인 아토믹 디자인 패턴에 대해 소개합니다.저만의 아토믹 패턴 노하우도 작성했으니 많은 의견 부탁드립니다. 아토믹 패턴은 NestJS에서도 일부 확인할 수 있

aierse.tistory.com

 

[Modern][리액트] 한국인이 만든 국산 모달 소개

기존의 리액트 모달 라이브러리는 유연함과 확장성을 가지고 있지만 너무 무겁다는 단점이 있습니다.문서가 영문이다보니 어떤 기능이 있는지도 찾기 어렵죠. 모달의 핵심적인 기능들을 구현

aierse.tistory.com

 

반응형

'웹 > React' 카테고리의 다른 글

[React] Three Dots 로딩 라이브러리 소개  (0) 2025.09.12
[React] 컴포넌트 인터페이스 개요 - 모듈 설계  (0) 2025.08.27
리액트 폴더 구조 우수 사례 - 아토믹 패턴  (0) 2025.08.02
[Modern][리액트] 한국인이 만든 국산 모달 소개  (0) 2025.08.01
리액트 프리랜서 체크리스트  (3) 2024.01.29
'웹/React' 카테고리의 다른 글
  • [React] Three Dots 로딩 라이브러리 소개
  • [React] 컴포넌트 인터페이스 개요 - 모듈 설계
  • 리액트 폴더 구조 우수 사례 - 아토믹 패턴
  • [Modern][리액트] 한국인이 만든 국산 모달 소개
Aierse
Aierse
리액트, 뷰 등 웹 개발의 모든 것
    반응형
  • Aierse
    <Aierse />
    Aierse
  • 전체
    오늘
    어제
    • 분류 전체보기
      • CS
      • 프로그래밍
        • Editer
      • Javascript
      • 웹
        • React
        • VueJS
        • NestJS
      • NodeJS
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • Github
  • 공지사항

  • 인기 글

  • 태그

    vscode
    TypeScript
    .vscode
    Workspace
    가독성
    async
    리액트
    vue3
    CI/CD
    AWS
    체크박스
    enum
    클린 코드
    nestjs
    전체선택
    NoSQL
    JavaScript
    프로그래밍
    Between
    lambda
    폴더 관리
    자바스크립트
    array every
    dynamodb
    JSDOC
    actions
    serverless
    react
    nodejs
    클린코드
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
Aierse
리액트 폴더 구조 우수 사례 - Container&Presenter 패턴
상단으로

티스토리툴바