요즘 프론트엔드 디자인 패턴, 뭐가 정답일까?

남다은·2025년 6월 9일
1

React

목록 보기
7/8
post-thumbnail

프론트엔드에서 디자인 패턴의 필요성

디자인 패턴은 단순한 추상 개념이 아니에요.

개발을 하다 보면 반복적으로 마주치는 문제가 생기는데, 이런 문제를 해결하기 위해 이미 검증된 방식(패턴)을 사용하는 게 바로 디자인 패턴이에요.

디자인 패턴을 몰라도 개발은 가능하지만, 알고 있으면 더 깔끔하고 확장성 있는 구조를 빠르게 만들 수 있어요.

지금 마주한 문제가 이미 다른 개발자들도 겪었던 문제라면, 그 해결책은 이미 패턴으로 정리돼 있을 수도 있기 때문이죠.


전통적인 디자인 패턴의 분류

분류설명대표 예시
생성 패턴객체를 유연하게 생성하는 방법싱글턴, 팩토리 메서드
구조 패턴객체나 클래스를 조합해 더 큰 구조로 만드는 방식어댑터, 데코레이터, 퍼사드
행동 패턴객체 간의 책임 분담과 흐름 제어 방식옵서버, 전략, 템플릿 메서드

핵심은 반복되는 문제를 일관된 방식으로 풀자는 사고예요.


프론트엔드에서 주로 쓰이는 디자인 패턴

프론트엔드는 사용자와 직접 맞닿는 영역이라, 백엔드와는 요구 사항이 달라요.
기존 객체지향 기반의 패턴보다 데이터 흐름, UI 구성, 상태 관리에 초점을 맞춘 패턴들이 더 많이 사용돼요.

예를 들어 이런 것들이 있어요 :

  • MVC, MVP, MVVM 아키텍처
  • Container–Presenter 패턴
  • Flux 패턴 (Redux 등)
  • Observer–Observable 패턴
  • MVI 아키텍처
  • Context API
  • Atomic 패턴
  • React Query
  • GraphQL (기술이지만 설계 방식에도 영향을 줘요)

많은 패턴들이 있지만, 이중에서 최근 많이 쓰이는 패턴 중심으로, 요즘 프론트엔드 개발이 어떤 흐름을 따르고 있는지 살펴보고자 해요.


🔍 최근 주목받는 패턴들과 방향성

1. Context API

컴포넌트 깊이에 상관없이 데이터를 전달하고 싶을 때

<MyContext.Provider value={someValue}>
  <Child />
</MyContext.Provider>

Context를 사용하면 props drilling 없이 전역 상태를 공유할 수 있어요.
다만 모든 상태를 Context에 넣으면 오히려 구조가 복잡해질 수 있으니, 꼭 필요한 경우에만 사용하는 게 좋아요.
*전역 상태를 언제 사용하면 좋을지에 대한 생각 정리

2. Atomic 패턴

상태를 간단하게 관리하고 싶을 때

Redux처럼 단계가 많은 상태 관리 방식은 구조가 무거워질 수 있어요.
Recoil, Jotai, Zustand 같은 라이브러리는 상태를 직접 get/set할 수 있게 설계돼 있어요.

const count = useCounterStore((state) => state.count);
const increment = useCounterStore((state) => state.increment);

보일러플레이트 없이 직관적으로 상태를 다룰 수 있지만, 동기화나 동시성 문제에는 주의가 필요해요.

3. TanStack Query (React Query)

서버 상태를 자동으로 관리하고 싶을 때

const query = useQuery({
  queryKey: ['user', id],
  queryFn: () => fetchUser(id),
});

React Query는 서버 상태를 가져오는 과정 전체를 자동화해줘요.
캐싱, 리패칭, 오류 처리까지 모두 포함돼 있어서, 복잡한 상태 관리 코드를 줄일 수 있어요.

4. GraphQL

필요한 데이터만 선택해서 가져오고 싶을 때

{
  user(id: 1) {
    name
    email
  }
}

GraphQL은 REST보다 유연하게 데이터를 다룰 수 있어요.
클라이언트가 필요한 필드만 지정해서 요청하고, 서버는 그에 맞춰 응답해줘요.
프론트엔드 중심의 개발 환경에서 유리한 구조를 만들 수 있어요.

5. Compound Components

관련된 컴포넌트를 하나처럼 조립해서 사용하고 싶을 때

<Tabs>
  <Tabs.List>
    <Tabs.Button />
  </Tabs.List>
  <Tabs.Panel />
</Tabs>

컴파운드 패턴은 여러 컴포넌트를 묶어 하나의 컴포넌트처럼 사용할 수 있게 해줘요.
구성은 자유롭고, 내부 로직은 감출 수 있어서 재사용성과 유연성을 높일 수 있어요.

6. HOC (Higher-Order Component)

공통 로직을 여러 컴포넌트에 적용하고 싶을 때

const withAuth = (Component) => (props) => {
  return isLoggedIn ? <Component {...props} /> : <LoginPage />;
};

HOC는 컴포넌트 외부에서 기능을 확장할 수 있는 패턴이에요.
요즘은 Hook과 컴포지션이 많이 쓰이지만, 특정 상황에서는 여전히 유용한 패턴이에요.


요즘 패턴들의 공통 흐름

  1. View와 Model의 역할을 명확하게 분리
  2. 중간 단계를 줄이고 구조는 단순하게
  3. 서버 중심의 데이터 흐름 강화
  4. 복잡한 상태 관리는 → 자동화/추상화 도구로 대체

항상 같은 정답이 있다기 보다는
상황에 따라 알맞은 패턴을 선택해야 해요.

상황패턴
전역 상태 공유가 많고 구조가 단순할 때Context API, Atomic 패턴
서버와 통신이 잦고 데이터 중심일 때React Query, GraphQL
상태가 복잡하고 비즈니스 로직이 많은 경우Redux Toolkit, Zustand
UI 컴포넌트를 조립형으로 구성하고 싶을 때Compound Components
공통 로직을 여러 컴포넌트에 재사용해야 할 때HOC (Higher-Order Component)

마무리하며

디자인 패턴은 강제 규칙의 개념보다는, 상황에 맞는 해결책을 찾기 위한 틀이에요.

따라서 어떤 패턴을 쓰는지가 중요한 게 아니라, 지금 마주한 문제에 어떤 구조가 가장 적합한 지를 판단할 수 있는 감각이 개발자에게 있어서 더 중요해질 거라고 생각해요.

profile
주저리주저리 생각 정리

0개의 댓글