Composition

- 영어 뜻 : 구성
- 여러개의 컴포넌트를 합쳐서 새로운 컴포넌트를 만드는 것
- 그래서 구성 보다는 합성이라는 단어가 어울림

 

조합 방법

Containment

- 담다, 포함하다
- 하위 컴포넌트를 포함하는 형태의 합성 방법
- SideBar나 Dialog 같은 Box 형태의 컴포넌트는 자신의 하위 컴포넌트를 미리 알 수 없다.
- children이라는 prop을 사용해서 조합

children 이라는 prop은 리액트에서 기본적으로 제공한다. 이것을 사용하면 해당 컴포넌트의 하위 컴포넌트가 모두 children으로 들어오게 된다.
이전에 createElement를 배웠을 때, ...children이 하위 컴포넌트라는 것을 배웠었다.
FancyBorder 컴포넌트 안에 있는 모든 JSX 태그는 children으로 전달됨!!

 

 

 

여러개의 children 집합이 필요한 경우 : 별도로 props를 정해서 각각 원하는 컴포넌트를 넣어주면 된다.

다음은 화면을 왼쪽과 오른쪽으로 분할해서 보여주는 역할을 하는 SplitPane 컴포넌트이다. 

 

App 이라는 컴포넌트에서는 SplitPane 컴포넌트를 사용하고 있는데, 여기서 left, right라는 두개의 props를 정의해서 그 안에 각각 다른 컴포넌트를 넣어주고 있다.

 

SplitPane 에서는 이 left, right 라는 props를 이용해서 각각 왼쪽과 오른쪽 화면을 분리해서 렌더링하여 보여준다.

 

이 처럼 여러개의 children 집합이 필요한 경우에는 별도의 props를 정의해서 사용하면 된다.

 

 

 

Specialization

- 전문화, 특수화

- 예) Welcome Dialog는 Dialog의 특별한 케이스다.

- 범용적인 개념을 구별이 되게 구체화 하는 것

- 기존의 객체지향 언어에서는 상속을 사용하여 Specialization을 구현한다. 그러나! BUT!

- React에서는 합성(Composition)을 사용하여 Specialization을 구현한다.

Dialog라는 범용적인 컴포넌트와 WelcomeDialog라는 특별한 컴포넌트

제목과 메세지를 WelcomeDialog에서 정의해서 제목과 메세지를 어떻게 사용하냐에 따라 인삿말 다이어로그가 되거나 경고 다이어로그가 된다.

 

 

 

Containment 와 Specialization을 같이 사용하기

children prop 을 통해 Dialog 하위 태그들을 Containment 방식 사용해서 불러 올 수 있으며, title 과 message prop으로 제목과 메세지 정의해서 특수화하여 사용하면 Specialization 역시 구현할 수 있다.

 

 

 

 

Inheritance

- Composition과 대비되는 개념

- 상속

- 다른 컴포넌트로부터 상속을 받아서 새로운 컴포넌트를 만드는 것

- 그러나 추천할 만한 사용은 아니다. 그래서 Composition 사용을 권장한다.

 

 

 

실습 : Card 컴포넌트 만들기

function Card(props) {
    const { title, backgroundColor, children } = props;

    return (
        <div
            style={{
                margin: 8,
                padding: 8,
                borderRadius: 8,
                boxShadow: "0px 0px 4px grey",
                backgroundColor: backgroundColor || "white",
            }}
        >
            {title && <h1>{title}</h1>}
            {children}
        </div>
    );
}

export default Card;

Card 컴포넌트는 하위 컴포넌트를 감싸서 카드 형태로 보여준다. Containment 와 Specialization 두가지 합성 방법을 모두 사용. children 부분이 Containment 부분이고, title과 backgroundColor 부분이 Specialization 부분이다.

 

 

import Card from "./Card";

function ProfileCard(props) {
    return (
        <Card title="Manse Kim" backgroundColor="#4ea04e">
            <p>안녕하세요, 만세입니다.</p>
            <p>리액트 공부 재미있네요.</p>
        </Card>
    );
}

export default ProfileCard;

ProfileCard 컴포넌트에서 Card 컴포넌트를 사용하여 타이틀에 이름을 넣고, 배경색깔 역시 넣는다.

children 으로는 간단한 자기소개 글을 넣었다.

 

 

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

import ProfileCard from './chapter_13/ProfileCard';

ReactDOM.render(
  <React.StrictMode>
  <ProfileCard />
  </React.StrictMode>,
  document.getElementById('root')
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

인덱스에서 렌더링하고 터미널에서 실행하면

 

 

제목과 배경색, 그리고 children이 합성되어 하나의 카드로 보여주는 것을 확인할 수 있다.

'React' 카테고리의 다른 글

[React] styled-component  (0) 2024.08.23
[React] Context  (0) 2024.08.21
[React] 실습 : 섭씨온도, 화씨온도 표시하기  (0) 2024.08.19
[React] Lifting State Up  (0) 2024.08.19
[React] Form과 Controlled Component  (0) 2024.08.18

+ Recent posts