노트

설정 기반 UI

Configuration-Driven UI

설계#pattern · 연결된 개념 7개

쉽게 말하면

설정 기반 UI는 화면을 코드로 하나하나 짜는 대신 공연 순서표만 적어 두면 무대 감독이 그대로 올려 주는 방식이에요. 순서를 바꾸고 싶으면 무대 장치는 그대로 두고 순서표만 고치면 돼요.

비유의 한계 순서표에 조건과 예외가 계속 붙으면 그 자체가 읽기 어려운 작은 언어가 돼요. 항목이 몇 개뿐이라면 설정 배열 없이 컴포넌트를 그냥 나열하는 편이 더 단순해요.

화면 구조를 컴포넌트를 나열한 코드가 아니라 설정 데이터(보통 배열)로 선언하고, 렌더러가 그 설정을 읽어 그리는 패턴. 구조를 바꿀 때 렌더링 코드 대신 데이터만 고친다.

type Section =
  | { type: 'banner'; id: string; image: string }
  | { type: 'products'; id: string; heading: string; query: string }
  | { type: 'custom'; id: string; render: () => ReactNode; shouldRender?: () => boolean }
 
const PAGE: Section[] = [
  { type: 'banner', id: 'hero', image: '/hero.png' },
  { type: 'products', id: 'best', heading: '베스트', query: 'sort=best' },
]
 
function Page() {
  return PAGE.filter(s => s.type !== 'custom' || (s.shouldRender?.() ?? true)).map(s => {
    switch (s.type) {
      case 'banner': return <Banner key={s.id} src={s.image} />
      case 'products': return <ProductList key={s.id} heading={s.heading} query={s.query} />
      case 'custom': return <Fragment key={s.id}>{s.render()}</Fragment>
    }
  })
}

이 구조는 몇 가지 생각이 겹친 것이다.

  • 선언적 렌더링(Declarative Rendering): 어떻게 그릴지가 아니라 무엇을 그릴지를 적는다(선언형과 명령형 프로그래밍)
  • 판별 유니언(Discriminated Union): type 필드로 항목 종류를 나눠 각 항목에 맞는 속성을 타입으로 보장한다(판별 유니언)
  • 전략(Strategy): 항목마다 render·shouldRender 함수를 두면 렌더링 방식을 항목이 고른다(전략 패턴)

같은 설정 배열에서 탭 메뉴·목차·스크롤 위치 같은 파생 UI도 함께 만들 수 있어, 구조 정보가 한곳에만 있게 된다(DRY 원칙). 라우터의 라우트 설정, 폼 라이브러리의 필드 설정, Storybook의 스토리 설정(Storybook)이 같은 계열이다.

설정에 조건과 예외가 계속 늘면 설정 자체가 읽기 어려운 작은 언어가 된다. 항목이 몇 개뿐이라면 컴포넌트를 그냥 나열하는 편이 단순하다(YAGNI).

연결된 개념

이 노트를 가리키는 문서

뜻이 가까운 노트

  • React Testing Library

    React Testing Library(RTL)는 컴포넌트를 jsdom 같은 테스트용 DOM(Document Object Model) 환경에 렌더하고, 사용자가 실제로 쓰는 방식으로 요소를 찾고 조작하게 해 주는 테스트 도구다. 내부 구현(state, 메서드)이 아니라 화면에 보이는 동작을 검증하라는 철학을 강하게 가진 라이브러리다.

  • 하이드레이션

    하이드레이션(Hydration)은 서버가 미리 렌더해 보낸 HTML(HyperText Markup Language)을 클라이언트에서 다시 만들지 않고, 그 DOM(Document Object Model)에 React 컴포넌트를 연결해 이벤트 핸들러와 상태를 붙이는 과정이다(hydrateRoot). Dan Abramov의 비유로는 "마른 HTML에 상호작용이라는 물을 주는 일"이다.

  • 구조적 공유

    구조적 공유(Structural Sharing)는 새 버전의 데이터를 만들 때 바뀌지 않은 부분은 이전 버전의 객체를 그대로 가리키게 하는 기법이다. 바뀐 노드와 그 노드까지 올라가는 경로만 새로 만들고, 나머지 가지는 두 버전이 함께 쓴다. 불변 데이터를 다루면서도 매번 전체를 복사하지 않게 해 준다.

  • React로 보는 SOLID

    SOLID는 원래 객체 지향 설계 원칙이지만 React 컴포넌트·props·훅에도 그대로 옮겨 볼 수 있다. 원칙 자체보다 "어떤 코드 모양이 되는가"를 짧게 정리한다.

  • Activity와 숨겨진 라우트 보존

    Activity는 React 19.2의 컴포넌트로, UI를 언마운트하지 않고 display: none으로 숨기면서 state와 DOM(Document Object Model)을 보존한다. 숨기는 동안 Effect는 정리(cleanup)된다. 예전 이름은 Offscreen이다.

보기 옵션