1. 컴포넌트단위로 합성(composition) vs 상속(inheritance)
React는 강력한 구성 모델을 가지고 있어서, 코드를 재사용하려면 상속 대신 합성을 사용하는 것이 좋습니다.
상속(inheritance)- extends 키워드를 사용해서 부모의 모든 속성과 메서드를 물려받는 방법
- 상속은 부모와 자식간에 의존성이 강하게 결합되어있어서 유연함이 부족하므로 좋은 방법은 아님
컴포넌트단위로 합성(composition)- 컴포넌트끼리 합쳐서 사용하는 방법
- Facebook에서도 수천개의 컴포넌트를 사용하고 있지만 상속을 안쓰고, Props 와 컴포지션을 사용
UI가 아닌 기능을 여러 컴포넌트에서 재사용하기를 원한다면, 별도의 JavaScript 모듈로 분리하는 것이 좋습니다.
상속받을 필요없이, 컴포넌트에서 해당 함수, 객체, 클래스 등을 import 하여 사용할 수 있습니다.
2. Containment = 컴포넌트에서 다른 컴포넌트를 담기
어떤 컴포넌트들은 어떤 자식 엘리먼트가 들어올 지 미리 예상할 수 없는 경우가 있습니다.
범용적인 ‘박스’ 역할을 하는 Sidebar 혹은 Dialog와 같은 컴포넌트에서 특히 자주 볼 수 있습니다.
이러한 컴포넌트에서는자식 prop을 사용하여 자식 엘리먼트를 출력에 그대로 전달하는 것이 좋습니다.
1function FancyBorder(props) {2return <div className={'FancyBorder FancyBorder-' + props.color}>{props.children}</div>3}45function WelcomeDialog() {6// <FancyBorder> JSX 태그 안에 있는 것들이 FancyBorder 컴포넌트의 자식 prop으로 전달7return (8<FancyBorder color="blue">9<h1>제목</h1>10<p>설명 뭐시기</p>11</FancyBorder>12)13}1415const root = ReactDOM.createRoot(document.getElementById('root'))16root.render(<WelcomeDialog />)
3. Specialization(특수화)
때로는 어떤 컴포넌트의 “특수한 경우”인 컴포넌트를 고려해야 하는 경우가 있습니다.
예를 들어, WelcomeDialog는 Dialog의 특수한 경우라고 할 수 있습니다.
1function FancyBorder(props) {2return <div className={'FancyBorder FancyBorder-' + props.color}>{props.children}</div>3}45function Dialog(props) {6return (7<FancyBorder color="blue">8<h1 className="Dialog-title">{props.title}</h1>9<p className="Dialog-message">{props.message}</p>10</FancyBorder>11)12}1314// 특수 기능을 가진 WelcomeDialog15function WelcomeDialog() {16return <Dialog title="특수화" message="쉽네" />17}
더 “구체적인” 컴포넌트가 “일반적인” 컴포넌트를 렌더링하고 props를 통해 내용을 구성합니다.