본문 바로가기

Today Learning _

Part 12-10. 리액트 살펴보기(합성(Composition) vs 상속(Inheritance))

합성과 상속은 객체 지향에서 기능의 재사용을 하기 위해 사용하는 대표적인 기법입니다.
리액트는 합성 모델을 가지고 있으며 상속 대신 합성을 사용해
컴포넌트 간에 코드를 재사용하는 것이 좋습니다.

 

상속(Inheritance)
다른 부모 클래스를 먼저 만든 후 자식 클래스가 부모의 클래스를 상속받습니다.

IS-A 관계

합성(Composition)
서로 다른 객체를 여러 개 붙여서 새로운 기능이나 객체를 구성합니다.
일반적으로 합성할 클래스를 변수에 할당 후 사용하는 구조입니다.
상속과는 다르게 클래스간의 유기적으로 서로의 클래스를 융통성 있게 합성할 수 있습니다. 

HAS-A 관계

 

 

 

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

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

이러한 컴포넌트에서는 특수한 children prop을 사용하여 자식 엘리먼트를 출력에 그대로 전달하는 것이 좋습니다.

 

 

FancyBorder 컴포넌트 입니다 : 

 

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

 

FancyBorder을 받아 WelcomeDialog에 사용했습니다 :

 

해당 컴포넌트의 UI가 나타난 것입니다.
FancyBorder에서 prop을 가져와 color를 blue로 지정했습니다.(css에 적용해놓은 것)
그리고 내부에 각각의 콘텐츠를 적어줍니다.

 

 

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

 

 

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

 

 

 

 

<Contacts />와 <Chat />  같은 React 엘리먼트는 단지  객체이기 때문에 다른 데이터처럼
prop 만으로 전달할 수 있습니다. 이런 접근은 다른 라이브러리의  "슬롯(slots)"과 비슷해 보이지만
리액트에서 prop으로 전달할 수 있는 것에는 제한이 없습니다.

 

 

해당 컴포넌트의 css 코드입니다 :

 

해당 컴포넌트의 css 코드입니다 :

 

 

 

UI에 나타난 결과 값입니다 :

 

 

 

 

 


 

 

 

특수화

때론 어떤 컴포넌트의 특수성을 고려해야 하는 경우가 있습니다.
예를 들어 WelcomeDialog는 Dialog의 특수한 경우라고 할 수 있습니다.

리액트에서 이것을 합성을 통해 해결할 수 있습니다.
더 구체적인 컴포넌트가 일반적인 컴포넌트를 렌더링한 후 props를 통해 내용을 구성합니다.

 

 

Dialog 컴포넌트에서 각각 props.title과 props.messgae를 변수로 지정한 후
WelcomeDialog에서 title과 message값을 받아서 출력할 수 있습니다.

 

합성은 클래스로 정의된 컴포넌트에서도 동일하게 적용됩니다.

 

 

 

 

 

해당 Dialog 컴포넌트를 props.children을 지정해 넘겨줄 수 있도록 만든다.
SignUpDialog 컴포넌트에서 handleChange(바뀌는 값 = 사용자 입력값)과
handleSignup(누르는 것)을 생성한 후 state 값으로 login을 지정한다.
이후 Dialog tilte과 message를 지정하고 input value의 값을 this.state.login으로 지정한다.
또한 바뀌는 값은 onChange를 this.handleChange로 지정한다. 
누르는 값을 onClick 이벤트를 지정해 this.handleSignUp으로 지정한다.

handleChange이벤트를 setState를 통해 e.target.value의 값으로 출력되게 만든다.
handleSignUp 이벤트 마찬가지로 지정하는데, alert를 띄워 문자와
사용자가 입력한 값 ${this.state.login}을 보여줄 수 있도록 한다.

 

 

사용자가 값을 입력한 후 결과 값을 누르면 
경고창에 사용자가 입력한 값이 뜹니다 :

 

 

 


 

 

 

상속은 사용하면 안될까요?

Facebook에서는 수천 개의 리액트 컴포넌트를 사용하지만
컴포넌트를 상속 계층 구조로 작성을 권장할만한 사례를 찾지 못했습니다.

props와 합성은 명시적이고 안전한 방법으로 

컴포넌트 모양과 동작을 커스터마이징하는데 필요한 모든 유연성을 제공합니다. 

컴포넌트가 원시 타입의 값, React 엘리먼트 혹은 함수 등 어떠한 props도 받을 수 있습니다.

UI가 아닌 기능을 여러 컴포넌트에서 재사용하기 원한다면 별도의 Javascript 모듈로 분리하는 것이 좋습니다.
컴포넌트에서 해당 함수, 객체, 클래스 등을 import 하여 사용할 수 있습니다. 

 

 

 

 

 

참고자료 

 

합성 (Composition) vs 상속 (Inheritance) – React

A JavaScript library for building user interfaces

ko.reactjs.org