View

반응형

합성 컴포넌트란?

리액트 문서에는 "React는 강력한 합성 모델을 가지고 있으며 상속 대신 합성을 사용하여 컴포넌트 간에 코드를 재사용하는 것이 좋습니다."라고 합니다. 카카오 FE 기술 블로그에서는 "합성 컴포넌트 패턴은 하나의 컴포넌트를 여러가지 집합체로 분리한 뒤, 분리된 각 컴포넌트를 사용하는 쪽에서 조합해 사용하는 컴포넌트 패턴을 의미합니다."라고 하네요.

 

저는 합성 컴포넌트를 여러 컴포넌트들을 조합해 만든 컴포넌트로 재사용성을 위한 코드 패턴이라고 이해했습니다...

 

이번 포스팅은 리액트 문서를 기반으로해서 제 생각을 첨언하는 형식으로 포스팅 해보겠습니다.

컴포넌트에서 다른 컴포넌트를 담기

어떤 컴포넌트들은 어떤 자식 엘리먼트가 들어올지 미리 예상할 수 없는 경우가 있습니다. 범용적인 ‘박스’역할을 하는 Sidebar 혹은 Dialoag와 같은 컴포넌트에서 자주 볼 수 있습니다.

 

이러한 컴포넌트에서 children prop을 사용해 자식 엘리먼트를 출력에 그대로 전달하는 것이 좋습니다. FancyBorder라는 박스 역할을 하는 컴포넌트를 생성해보겠습니다.

function FancyBorder(props) {
	return (
		<div className={'FancyBorder FancyBorder-' + props.color}>
			{props.children}
		</div>
	);
}

 

이러한 방식으로 컴포넌트에서 JSX를 중첩하여 임의의 자식을 전달할 수 있습니다.

function WelcomeDialog() {
	return (
		<FancyBorder color="blue">
			<h1 className="Dialog-title">
				Welcome
			</h1>
			<p className="Dialog-message">
				Thank you for visiting our spacecraft!
			</p>
		</FancyBorder>
	);
}

<FancyBorder> JSX 태그 안에 있는 것들이 FancyBorder 컴포넌트의 children prop으로 전달됩니다. FancyBorder는 {props.children}을 <div> 안에 렌더링하므로 전달된 엘리먼트들이 최종 출력됩니다.

 

또한 컴포넌트에 여러 개의 컴포넌트들을 전달받아야 하는 경우도 있습니다. 리액트 문서에서는 이를 “구멍”이라고 표현하네요.

function SplitPane(props) {
	return (
		<div classNam="SplitPane">
			<div className="SplitPane-left">
				{props.left}
			</div>
			<div className="SplitPane-right">
				{props.right}
			</div>
		</div>
	);
}

function App() {
	return (
		<SplitPane left={<Contacts/>} right={<Chat/>} />
	)
}

 

컴포넌트는 리액트 엘리먼트입니다. 즉, 자바스크립트의 객체죠. 따라서 객체이기 때문에 다른 데이터처럼 prop으로 전달할 수 있습니다. 이처럼 리액트에서는 prop으로 전달할 수 있는 것에 제한이 없습니다.

 

특수화

리액트 문서에는 “특수화”라고 표기되어 있는 부분인데, 글을 읽는 것보다 코드를 보는 것이 이해하는데 더 빠를 것 같습니다.

function Dialog(props) {
  return (
    <FancyBorder color="blue">
      <h1 className="Dialog-title">
        {props.title}
      </h1>
      <p className="Dialog-message">
        {props.message}
      </p>
    </FancyBorder>
  );
}

function WelcomeDialog() {
  return (
    <Dialog
      title="Welcome"
      message="Thank you for visiting our spacecraft!" />
  );
}

리액트 문서에서는 “React에서는 이 역시 합성을 통해 해결할 수 있습니다. 더 “구체적인” 컴포넌트가 “일반적인” 컴포넌트를 렌더링하고 props를 통해 내용을 구성합니다.”라고 하는데, Dialog처럼 범용적으로 재사용이 가능하게 만든 컴포넌트를 “구체적인” 컴포넌트라 명시하고, 이를 한 번더 감싸서 props로 출력하고자 하는 데이터를 전달해주는 것이 “일반적인” 컴포넌트(위의 코드에서 WelcomeDialog 부분)의 역할인 것 같습니다.

 

“일반적인” 컴포넌트는 Wrapper 컴포넌트같은 느낌이네요. 이처럼 Wrapper 컴포넌트에서<Dialog> 컴포넌트에 용도에 맞게 데이터를 전달해주면 상황에 따라 정말 유용하게 쓰일 수 있겠네요.

 

리액트 문서 외에도 카카오 FE 기술블로그에서 실제로 합성 컴포넌트를 도입한 예와 어떤 경우에 합성 컴포넌트를 사용하면 좋은지에 대해 예시 코드와 함께 정말 잘 설명되어져 있습니다. 궁금하신 분들은 여기 들어가셔서 한 번 읽어보세요…!

 

반응형
Share Link
reply
«   2025/07   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31