ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [ReactJS] Composition vs Inheritance
    Programming/ReactJS 2022. 12. 1. 23:32

    Composition

    여러 개의 컴포넌트를 합쳐서 새로운 컴포넌트를 만드는 것을 의미한다. 그래서 합성이라는 의미에 더 가깝다. 조합 방법에 따라 컴포지션 사용 기법이 나뉘는데, 다음과 같다.

    Containment

    하위 컴포넌트를 포함하는 형태의 합성 방법이다. 보통 Sidebar나 Dialog 같은 Box 형태의 컴포넌트는 자신의 하위 컴포넌트를 미리 알 수 없다. 리액트 props의 children 형태를 사용하는데, 아래의 코드를 참고하자면 {props.children}을 사용하면서 해당 컴포넌트의 하위 컴포넌트가 모두 children으로 들어오게 된다.

    function FancyBorder(props) {
        return (
            <div className={'FancyBorder FancyBorder-' + props.color}>
                {props.childeren}
            </div>
        )
    }
    function WelcomeDialog(props) {
        return (
            <FancyBorder color = "blue">
                <h1 className="Dialog-title">
                    어서오세요
                </h1>
                <p className="Dialog-message">
                    우리 사이트에 방문하신 것을 환영합니다 !
                </p>
            </FancyBorder>
        )
    }

    여러 개의 children 집합이 필요한 경우

    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

    범용적인 개념을 구별이 되도록 구체화하는 것을 의미한다. 기존의 객체지향에서는 상속을 사용하여 Specialization을 구현하는데, 리액트에서는 합성을 이용하여 이를 구현하게 된다.

    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 = "어서오세요"
                message = "우리 사이트에 방문하신 것을 환영합니다 !"
            />
        )
    }

    Containment와 Specialization의 동시 사용법

    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 = "닉네임을 입력해주세요"> // Specialization
                <input
                    value={nickname}
                    onChange={handleChange} />
                    <button onClick={handleSignUp}>
                        가입하기
                    </button> // Containment
            </Dialog>
        )
    }

    Inheritance

    Inheritance는 앞의 Composition과 대비되는 상속의 의미를 가지는데, 부모 클래스의 속성을 상속 받는 객체지향에서의 의미와 동일하다. 그러나 리액트에서는 상속보다 컴포지션을 사용하는 방법이 더 좋다는 결론이 나왔다고 한다. 결론은 복잡한 컴포넌트를 쪼개서 여러 개의 컴포넌트로 만들고, 만든 컴포넌트들을 조합해서 새로운 컴포넌트를 만들어야 한다.

    Card.jsx

    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",
                }}
            >
                {/* specialization */}
                {title && <h1>{title}</h1>}
                {/*containment*/}
                {children}
            </div>
        )
    }
    
    export default Card;

    ProfileCard.jsx

    import Card from "./Card";
    
    function ProfileCard(props) {
        return (
            <Card title = "cdd" backgroundColor = "#4ea04e">
                <p>안녕하세요, cdd입니다.</p>
                <p>리액트 개발을 공부중입니다.</p>
            </Card>
        )   
    }
    
    export default ProfileCard;

    ※ 본 게시글은 소플님의 강의 영상을 참고하여 작성되었습니다. 개인적인 공부 목적으로 사용하고 있고, 문제 시 비공개 전환하도록 하겠습니다.

    'Programming > ReactJS' 카테고리의 다른 글

    [ReactJS] Lifting State Up  (0) 2022.12.01
    [ReactJS] Forms  (0) 2022.12.01
    [ReactJS] List and Keys  (0) 2022.11.30
    [ReactJS] Conditional Rendering  (0) 2022.11.30
    [ReactJS] Handling Events  (0) 2022.11.30

    댓글