결론부터 말하면 React에서는 강력한 합성모델을 가지고 있으며 상속으로 코드를 재사용하기 보단 합성을 이용해서 컴포넌트간에 코드를 재사용하는것이 좋다.
(합성이란 컴포넌트 합성 컴포넌트편에서 컴포넌트는 자신의 출력에 다른 컴포넌트를 참조할수 있다로 배웠고 지금까지 많은 예제를 하며 경험해왔다.)
합성을 많이 해봤지만 다시한번 하면서 경험해보자.
어떠한 컴포넌트는 어떤 자식엘리먼트가 올지 예상할수 없는 경우가 많다. 구체적인 컴포넌트보단 일반적인 컴포넌트가 그런경우가 많다. 예를들면 Header컴포넌트는 안에 어떤 리스트가 올지 모르겠다.
이러한 경우 props children을 통해서 자식 엘리먼트를 그대로 출력하는 것이 좋다.
(우리는 React는 단방향 데이터 흐름이라는 것을 알고있다.
이는 컴포넌트간 props
를 통해서 데이터가 전달되기 때문이란 것도 알고 있다.
그리고 props
는 컴포넌트에 전달된 속성과 children이 담겨있는 객체라는 것도 알고있다.)
단순히 전달되는 자식엘리먼트를 그대로 받아서 출력할 때와 자식 엘리먼트를 다양하게, 여러개의 구멍으로 받는 경우가 존재한다.
먼저
const FoodIntroduction = (props) => {
return <div>{props.children}</div>;
};
const BananaIntroduction = () => {
return (
<FoodIntroduction>
<div>
<h1>바나나</h1>
<p>껍질은 노랗고 속은 하얗습니다.</p>
</div>
</FoodIntroduction>
);
};
BananaIntroduction컴포넌트가 출력하는 곳에서 FoodIntroduction컴포넌트를 참조하는 컴포넌트 합성이다.
이 경우 단순히 내용만 FoodIntroduction에게 그대로 전달하기 때문에 FoodIntroduction에선 children props로 받는 것이 좋다.
const FoodIntroduction = (props) => {
return (
<div>
<div>{<Apple />}</div>
<div>{<Banana />}</div>
</div>
);
};
const Apple = () => <h1>사과</h1>;
const Banana = () => <h1>바나나</h1>;
const Food = () => {
return <FoodIntroduction apple={<Apple />} Banana={<Banana />} />;
};
이런식으로 컴포넌트를 다른 컴포넌트로 전달하며(= 컴포넌트 출력에 다른컴포넌트를 참조하는 방법 = 컴포넌트 합성) props
를 사용할수 있고 props는 오브젝트이고 이 props 오브젝트 중 children을 이용하거나, props 속성을 이용해 리액트 엘리먼트를 전달하수 있다.
리액트 엘리먼트는 객체이므로 가능하다. 너무 이상하다, 너무 이질감든다고 생각할필요없이 JS의 오브젝트(객체)를 props로 넘긴다고 생각하자!
일반적인 컴포넌트의 구체적인 컴포넌트를 고려할 때가 종종있다.
예를들면 음식 소개 컴포넌트인 일반적인 컴포넌트에서 치킨 소개하는 구체적인 컴포넌트인 경우이다.
이럴때 컴포넌트 합성을 이용한다. 즉, 구체적인 컴포넌트가 출력하는 부분에 일반적인 컴포넌트를 참조(합성)하고 전달되는 구체적인 데이터는 props로 전달되면된다. 이게 입력되는 구멍이 하나면 props.children이고 아니면 props속성이겠다. (참고로 props는 읽기전요! props받는 컴포넌트는 순수함수! 함수라면)
(이부분은 직접 만들어보거나 코드를 보면 바로이해할수 있는 부분.!)
const FoodIntroduction = (props) => {
return (
<div>
<h1>{props.name}</h1>
<p>{props.description}</p>
</div>
);
};
const Chicken = () => {
return <FoodIntroduction name="치킨" description="닭을 튀긴 요리입니다." />;
};
일반적인 FoodIntroduction컴포넌트를 구체적인 Chicken컴포넌트에서 합성 시킨거고 props로 구체적인 정보를 전달한 것이다.
이렇게 컴포넌트 합성을 이용해서 코드를 재사용할수있다.
피자를 소개한다하면
const Pizza = () => {
return <FoodIntroduction name="피자" description="치즈랑 빵입니다." />;
};
이렇게 간단하게 피자 컴포넌트만 만들면 쉽게 FoodIntroduction인 일반적인 컴포넌트의 코드를 재사용할수 있다.
이렇게 React에서는 합성을 통해서 컴포넌트를 계층구조로 작성하고 그에 맞게 컴포넌트의 코드도 재사용이 가능하다.
위에서 본거와 같이 props로 전달되는 데이터는 다른 컴포넌트(리액트 엘리먼트 === 객체)일수도 있고 primitive type일수도 있고 state끌어올리기에서 사용한 함수 일수도 있다.
즉, 어떠한 녀석도 props로 받을수 있고 이 props와 합성을 통해 코드의 유연성을 제공한다.
참고로 React는 UI라이브러리이다. 즉 View에 해당되기 때문에 UI외의 기능에 대해선 다른 모듈로 만들어 UI부분과 분리 하는 것이 좋다.
위 내용은 공식문서를 보면서 나름대로 공부한 내용을 정리한 문서입니다.
https://ko.reactjs.org/docs/composition-vs-inheritance.html