FrontEnd/React

Composition vs Inheritacne

Composition

여러 개의 컴포넌트를 합쳐서 새로운 컴포넌트를 만드는 것 (합성)

 

Containment

하위 컴포넌트를 포함하는 형태의 합성 방법

Sidebar나 Dialog 같은 Box형태의 컴포넌트는 자신의 하위 컴포넌트를 미리 알 수 없다.

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

// children이라는 prop을 사용해서 조합
// children prop을 사용한 FancyBorder 컴포넌트
function FancyBorder(props) {
    return (
        <div className={'FancyBorder FancyBorder-' + props.color}>
            {props.children}
        </div>
    );
}

React.createElement(
    type,
    [props],
    [...children]
);

// FancyBorder 컴포넌트 안에 있는 모든 JSX 태그는 children으로 전달됨!
function WelcomeDialog(props) {
    return (
      <FancyBorder color="blue">
        <h1 className="Dialog-title">
          Welcome
        </h1>
        <p className="Dialog-message">
          Thank you for visiting our spacecraft!
        </p>
      </FancyBorder>
    );
  }

 

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

function SplitPane(props) {
    return (
      <div className="SplitPane">
        <div className="SplitPane-left">
          {props.left}
        </div>
        <div className="SplitPane-right">
          {props.right}
        </div>
      </div>
    );
  }
  
  function App(props) {
    return (
      <SplitPane
        left={
          <Contacts />
        }
        right={
          <Chat />
        } />
    );
  }

 

Specialization

특수화

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

WelcomeDialog는 Dialog의 특수한 경우라고 할 수 있다.

객체지향의 경우 상속(Inheritance)을 통해 Specialization을 구현하나

React의 경우 합성(Containment)을 사용하여 Specialization을 구현한다.

 

// 더 구체적인 컴포넌트가 일반적인 컴포넌트를 렌더링하고 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(props) {
    return (
      <Dialog
        title="Welcome"
        message="Thank you for visiting our spacecraft!" />
    );
  }

 

Containment와 Specialization을 같이 사용하기

import { useState } from "react";

function Dialog(props) {
    return (
      <FancyBorder color="blue">
        <h1 className="Dialog-title">
          {props.title}
        </h1>
        <p className="Dialog-message">
          {props.message}
        </p>
        {props.children}
      </FancyBorder>
    );
  }

  function SignUpDialog(props) {
    const [nickname, setNickname] = useState('');

    const handleChange= (event) => {
        setNickname(event.target.value);
    }

    const handleSignUp = () => {
        alert('어서 오세요, ${nickname}님!');
    }

    return (
        <Dialog
        title="화성 탐사 프로그램"
        message="닉네임을 입력해 주세요.">
        <input
            value={nickname}
            onChange={handleChange} />
        <button onClick={handleSignUp}>
            가입하기
        </button>
        </Dialog>
    );
  }

 

Inheriatance

상속

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

Meta에서 상속보다 합성을 추천

 

복잡한 컴포넌트를 쪼개서
여러 개의 컴포넌트로 만들고,
만든 컴포넌트를 조합해서
새로운 컴포넌트를 만들자!

 

Reference

 

인프런 - 처음 만난 리액트(React)

 

[지금 무료] 처음 만난 리액트(React) | Inje Lee (소플) - 인프런

Inje Lee (소플) | 자바스크립트와 CSS 기초 문법과 함께 리액트의 기초를 탄탄하게 다질 수 있습니다., 깔끔한 강의자료, 꼼꼼한 설명으로쉽게 배우는 리액트 강의입니다. 👨‍🏫 리액트의 세계로

www.inflearn.com

https://ko.legacy.reactjs.org/docs/composition-vs-inheritance.html

 

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

A JavaScript library for building user interfaces

ko.legacy.reactjs.org

 

https://github.com/soaple/first-met-react-practice/tree/master/src/chapter_13

 

first-met-react-practice/src/chapter_13 at master · soaple/first-met-react-practice

소플의 처음 만난 리액트 실습 소스코드. Contribute to soaple/first-met-react-practice development by creating an account on GitHub.

github.com

 

'FrontEnd > React' 카테고리의 다른 글

Styling  (0) 2024.05.08
Context  (0) 2024.04.30
Lifting State Up  (0) 2024.04.24
Forms  (0) 2024.04.23
Lists and Keys  (0) 2024.04.22