[React Docs 번역]Composition vs Inheritance

김승엽
Berkbach
5 min readApr 25, 2020

--

Photo by davisco on Unsplash

🤼‍♂️ 합성 vs 상속

React는 강력한 합성 모델을 가지고 있습니다. 또한 상속 대신 합성을 사용해서 컴포넌트 간에 코드 재사용을 권장합니다. 이 섹션에서 React를 입문하는 개발자가 겪는 상속에 관한 몇 가지 문제와 어떻게 해결하는지 다뤄보겠습니다.

📦 다른 컴포넌트 담기

몇개의 컴포넌트는 어떤 자식 element로 들어올지 미리 알지 못합니다. 무언가를 담는 “박스” 역할을 하는 Sidebar , Dialog 같은 컴포넌트에서 쉽게 볼 수 있습니다. 이러한 컴포넌트는 children props를 사용해서 자식 element 를 바로 출력하도록 권장합니다.

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

다른 컴포넌트에서 중첩된 JSX로 임의의 자식을 전달할 수 있습니다.

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

<FancyBorder> JSX 태그 안에 모든 요소는 FancyBorder 컴포넌트에게 children props 로 전달됩니다. FancyBorder<div> 안에 {props.children} 을 렌더링하기 때문에 전달되는 element 는 최종 출력에 나타납니다.

흔하진 않지만 때때로 컴포넌트 안에 여러 개의 “구멍” 이 필요할 경우가 있습니다. 이런 경우에는 children 대신 자신만의 고유한 방식을 사용할 수 있습니다.

<Contacts /><Chat /> 같은 React element 는 객체입니다. 그래서 다른 데이터처럼 props 로 전달이 가능합니다. 이런 접근은 다른 라이브러리의 “slots” 을 떠올리게 합니다. 하지만 React에서는 제한 없이 props 로 전달할 수 있습니다.

✨ 특수화

때때로 다른 컴포넌트와 다른 특별한 컴포넌트에 대해 고려합니다. 예로 WelcomeDialogDialog 의 특별한 경우라고 할 수 있습니다. React 에서는 이것도 합성을 통해 해결합니다. 더 구체적인 컴포넌트가 더 일반적인 컴포넌트를 렌더링하고 props 로 설정합니다.

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!"
/>
);
}

합성은 클래스형 컴포넌트에서도 정상적으로 작동합니다.

🤔 그렇다면 상속은 ?

페이스북에서 수천개의 컴포넌트를 사용하지만 컴포넌트를 상속 계층 구조로 작성을 권장할만한 사례를 아직 찾지 못했습니다. props와 합성은 명확하고 안전한 방향으로 컴포넌트의 모양과 동작을 유연하게 커스터마이징할 수 있도록 제공합니다. 컴포넌트가 원시적인 값, React element, 함수 같은 임의의 props를 받을 수 있다는 것을 기억하세요.

만약 UI가 아닌 기능적인 컴포넌트를 재사용하고 싶다면 독립된 JS 모듈로 추출하는 것을 추천합니다. 컴포넌트는 상속 없이 해당하는 함수, 객체, 클래스를 임포트해서 사용할 수 있습니다.

📚 정리 및 참고 자료

  1. 자식 element 를 바로 출력하려면 children props 를 사용하면 됩니다.
  2. Vue에서의 Slot
  3. UI가 아닌 기능적인 컴포넌트를 재사용하고 싶다면 독립된 JS 모듈로 추출하는 것을 추천합니다.

--

--