Container-Presenter 패턴

박준수·2023년 4월 17일
0

Container-Presenter 패턴이란?

  • Container-Presenter 패턴은 프론트엔드 개발에 사용되는 디자인 패턴으로 사용자 인터페이스의 로직과 표시 책임을 별도의 컴포넌트로 나누어 관심사 분리 원칙을 따릅니다.
  • "Container"라고도 하는 컨테이너 구성 요소는 UI의 상태 및 비즈니스 로직 관리를 담당합니다. 일반적으로 외부 데이터 소스 또는 서비스에 연결되며 Presenter 구성 요소와 통신합니다.
  • “View Model" 또는 "컨트롤러"라고도 하는 Presenter 구성 요소는 컨테이너에서 상태를 수신하고 렌더링을 위해 View 구성 요소에 전달하는 역할을 합니다.
    • 컨테이너와 뷰 사이의 브리지로서 사용자 상호 작용을 처리하고 필요에 따라 컨테이너의 상태를 업데이트합니다.
  • "UI 구성 요소"라고도 하는 View 구성 요소는 사용자 인터페이스 렌더링을 담당합니다.
    • Presenter로부터 상태를 수신하여 사용자에게 표시합니다.
    • 프레젠터와 통신하여 상태에 대한 작업 또는 업데이트를 트리거합니다.

Container-Presenter 패턴은 왜 쓰일까?

  • 웹 서비스가 발전하게 되면서 이제는 하나의 Page단위가 아니라 Page안에 여러가지 모듈이 있고 Modal이나 여러 화면들이 하나의 화면에서 구성이 될 수 있도록 발전을 하게 됩니다.
  • 그래서 MVVM이 이제 화면단위가 아니라 조금 더 작게 재사용 할 수 있는 단위로 만들어서 조립을 하는 방식으로 발전을 하게 됩니다.
  • 이것이 우리는 이미 이제 익숙한 Component 패턴입니다.
  • 컨테이너-프레젠터 패턴은 상태 관리(컨테이너), 프리젠테이션 논리(프레젠터) 및 사용자 인터페이스 렌더링(뷰)의 문제를 분리하여 프런트엔드 애플리케이션의 모듈성을 좋게 만들고
  • 복잡한 UI 로직을 더 쉽게 관리할 수 있으며 관심사를 명확하게 분리할 수 있습니다.

Container-Presenter 패턴은 어떻게 쓰일까?

  • 컴포넌트는 재사용이 가능해야 한다는 원칙에 따라 가급적 비지니스 로직을 포함시키지 않으려고 개발을 했습니다.
  • 비지니스 로직이 들어가게 되면 컴포넌트의 재활용성은 상당히 떨어지게 됩니다.
  • 그래서 비즈니스 로직을 관장하고 있는 컴포넌트를 Container 컴포넌트라 그러고
  • 혹은 이제 비지니스 로직을 가지고 있지 않은 데이터만 뿌려주는 형태의 컴포넌트를 Presenter 컴포넌트로 분리하여
  • 최상단 혹은 1depth에 Container를 두고 비지니스 로직을 관리하는 Container-Presenter 아키텍쳐가 만들어집니다.

Container

import React, { useState, useEffect } from 'react';

const UserContainer = () => {
  const [user, setUser] = useState(null);
  const [isLoading, setIsLoading] = useState(true);

  useEffect(() => {
    // Fetch user data from API
    fetch('https://api.example.com/users/1')
      .then(response => response.json())
      .then(data => {
        setUser(data);
        setIsLoading(false);
      })
      .catch(error => {
        console.error('Error fetching user data:', error);
        setIsLoading(false);
      });
  }, []);

  if (isLoading) {
    return <div>Loading...</div>;
  }

  return (
    <div>
      {user ? (
        <UserPresenter user={user} />
      ) : (
        <div>No user data available.</div>
      )}
    </div>
  );
};

Presenter

import React from 'react';

const UserPresenter = ({ user }) => {
  return (
    <div>
      <h1>{user.name}</h1>
      <p>Email: {user.email}</p>
      <p>Phone: {user.phone}</p>
    </div>
  );
};

export default UserPresenter;

설명

  • 이 예제에서 컨테이너 구성 요소(UserContainer)는 API에서 사용자 데이터를 가져오고 로드 상태 및 사용자 데이터에 대한 상태를 관리하는 역할을 합니다.
  • Presenter 구성 요소(UserPresenter)는 소품으로 전달된 데이터를 기반으로 UI를 렌더링하는 역할을 합니다.
  • 이러한 관심사 분리를 통해 더 나은 코드 구성, 향상된 재사용성 및 더 쉬운 테스트가 가능합니다.

Props Drilling Problem

  • 이렇게 만들게 됐을 때 알게된 문제는 컴포넌트 구조가 복잡해짐에 따라 하위에 특정 값을 전달하기 위해서는 중간 레벨에 있는 컴포넌트들은 전부 그 props를 가지고 있어야 하는 문제가 발생합니다.

https://velog.velcdn.com/images%2Fteo%2Fpost%2F264171a3-3f2d-42c7-8375-44d877180c11%2Fimage.png

  • 이렇게 상단에 있는 데이터를 하단에 있는 props로 보내기 위해서 중간 계층에 있는 props를 하나씩 추가하는 문제를 Props Drilling Problem이라고 부릅니다.
  • 그래서 이러한 문제를 해결하기 위한 새로운 아키텍쳐를 생각합니다.

출처

https://velog.io/@teo/프론트엔드에서-MV-아키텍쳐란-무엇인가요#프롤로그

profile
심플한 개발자를 향해 한걸음 더 (과거 블로그 : https://crablab.tistory.com/)

0개의 댓글