노트

Render Props 패턴

Render Props

프론트엔드#react#pattern · 연결된 개념 7개

쉽게 말하면

Render Props는 빵집이 반죽(데이터)만 준비하고 어떤 모양으로 구울지는 손님이 건넨 틀(함수)에 맡기는 패턴이에요. 상태와 동작은 컴포넌트가, 무엇을 그릴지는 함수가 정해서 같은 로직을 여러 화면에 써요.

비유의 한계 틀을 여러 겹 끼우면 들여쓰기가 콜백 지옥처럼 깊어져요. 그래서 훅이 나온 뒤로는 useMouse 같은 커스텀 훅이 대부분을 대체했고, 지금은 라이브러리나 확장 슬롯에서 주로 써요.

Render Props는 무엇을 그릴지를 컴포넌트가 정하지 않고, prop으로 받은 함수가 정하게 하는 로직 재사용 패턴이다. 컴포넌트는 상태와 동작만 맡고 그 데이터를 함수에 넘긴다.

function MouseTracker({ children }) {
  const [pos, setPos] = useState({ x: 0, y: 0 })
  return <div onMouseMove={e => setPos({ x: e.clientX, y: e.clientY })}>{children(pos)}</div>
}
 
<MouseTracker>{({ x, y }) => <p>마우스: {x}, {y}</p>}</MouseTracker>
  • render라는 prop 대신 children을 함수로 쓰는 형태(function as children)가 흔하다
  • 장점: 로직과 UI가 분리되고, 같은 로직을 다른 화면에 재사용한다. 고차 컴포넌트(Higher-Order Component, HOC)보다 데이터 흐름이 눈에 보인다
  • 리스트 항목 끝에 버튼 영역만 갈아 끼우는 renderActions={item => …}처럼, 컴포넌트를 고치지 않고 확장하는 슬롯으로도 쓴다. 확장에 열려 있고 수정에 닫힌 구조다(React로 보는 SOLID)
  • 한계: 중첩되면 콜백 지옥처럼 들여쓰기가 깊어진다. 훅이 나온 뒤로는 const pos = useMouse() 같은 커스텀 훅이 대부분을 대체했다
  • 여전히 라이브러리(폼, 가상화, 헤드리스 UI(Headless UI))에서 쓰이고, 리렌더 범위를 좁히는 데도 도움이 된다(상태 내리기와 컴포지션으로 리렌더 줄이기)

같은 계열의 합성 패턴은 컴파운드 컴포넌트 패턴·Presentational·Container 컴포넌트, 함수를 넘겨 동작을 바꾸는 발상은 전략 패턴.

연결된 개념

이 노트를 가리키는 문서

뜻이 가까운 노트

  • 상태 패턴

    객체의 행동이 현재 상태에 따라 달라질 때, 상태마다 별도 객체를 두고 현재 상태 객체에 행동을 맡기는 패턴. 상태별 조건문이 메서드마다 반복되는 문제를 푼다.

  • 구조적 공유

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

  • React의 규칙과 렌더 순수성

    Rules of React는 React가 올바르게 동작하고 최적화하기 위해 코드가 지켜야 하는 규칙으로, 공식 문서가 세 가지로 정리한다. 핵심은 렌더가 순수한 계산이어야 한다는 것이다.

  • 컴포지트 패턴

    개별 객체(잎, Leaf)와 객체들의 묶음(가지, Composite)을 같은 인터페이스로 다뤄, 트리 구조를 재귀적으로 처리하는 패턴.

  • useActionState와 폼 액션

    React 19에서는 <form action={함수}>에 함수를 바로 넘길 수 있고, useActionState가 그 액션의 대기 상태와 마지막 결과를 한 훅으로 관리한다. useState + onSubmit + 로딩 플래그로 짜던 패턴을 대체한다.

보기 옵션