[React][Inflearn] 11. Composition vs Inheritance

sohwisu·2022년 9월 11일

[react][inflearn]

목록 보기
11/11

Composition

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

Composition 사용 기법

  • 여러개의 컴포넌트를 어떻게 합칠 것인가?

Containment

  • BOX형태의 컴포넌트는 자신의 하위 컴포넌트를 미리 알 수 없다

  • children이라는 prop을 사용해서 조합한다

  • 여러개의 children이 필요한 경우는?

  • left와 right등으로 나누어서 사용한다.

Specialization

  • 전문화, 특수화

  • 기존의 객체지향 언어에서는 상속을 사용하여 구현하였다.

  • React에선 Composition을 사용하여 Specialization을 구현한다.

Containment & Specialization

Inheritance

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

  • 페이스북에서 수천개의 React 컴포넌트를 사용했지만, 상속을 사용해서 컴포넌트를 만드는 것을 추천할만한 Use Case를 찾지 못했다.

즉, React에서는 상속을 사용 할 필요가 없다.

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

{Project Name} / src / Chapter11 / UserProfile.js

import React from 'react';

function FancyBorder(props) {
    return (
        <div style={Object.assign(props.style, {
            display: 'inline-block',
            borderStyle: 'solid',
            borderWidth: 2,
            borderColor: '#80d900',
            borderRadius: 16,
            textAlign: 'center' })}>
            <div style={{
                    padding: 8,
                    backgroundColor: '#80d900',
                    borderTopLeftRadius: 12,
                    borderTopRightRadius: 12 }}>
                <span style={{ fontSize: 16, }}>
                    {props.title}
                </span>
            </div>
            <div style={{ marginTop : 8 }}>
                {props.children}
            </div>           
        </div>
    )
}

const styles = {
    imageContainer: {
        width: 50,
        margin : 'auto',
    },
    image: {
        width: 50,
        height: 50,
        borderRadius: 25,
    },
    jobContainer: {
        padding : 8,
    },
    jobText: {
        fontSize : 16,
    },
};

class UserProfile extends React.Component {
    constructor(props){
        super(props);
    }

    render() {
        const  { user } = this.props

        return (
            <FancyBorder
                title={user.name}
                style={{width: 'calc(33.3% - 12px', margin: 4 }}>
                <div style={styles.imageContainer}>
                    <img
                        alt="profile"
                        src={user.image}
                        style={styles.image} />
                </div>
                <div style={styles.jobContainer}>
                    <span style={styles.jobText}>
                        {user.job}
                    </span>
                </div>
            </FancyBorder>
        )
    }
}

export default UserProfile;

{Project Name} / src / Chapter11 / UserProfileList.js

import { render } from '@testing-library/react';
import React from 'react';
import UserProfile from './UserProfile';

class UserProfileList extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            users: [
                {id: 1, name: 'Jaewon1', image:'https://upload.wikimedia.org/wikipedia/commons/8/89/Portrait_Placeholder.png', job:'Student1'},
                {id: 2, name: 'Jaewon2', image:'https://upload.wikimedia.org/wikipedia/commons/8/89/Portrait_Placeholder.png', job:'Student2'},
                {id: 3, name: 'Jaewon3', image:'https://upload.wikimedia.org/wikipedia/commons/8/89/Portrait_Placeholder.png', job:'Student3'},
                {id: 4, name: 'Jaewon4', image:'https://upload.wikimedia.org/wikipedia/commons/8/89/Portrait_Placeholder.png', job:'Student4'},
                {id: 5, name: 'Jaewon5', image:'https://upload.wikimedia.org/wikipedia/commons/8/89/Portrait_Placeholder.png', job:'Student5'},
                {id: 6, name: 'Jaewon6', image:'https://upload.wikimedia.org/wikipedia/commons/8/89/Portrait_Placeholder.png', job:'Student6'},
            ]
        }
    }
    render(){
        const { users } = this.state;
    
        return (
            <div>
                {users.map((user) => {
                    return (
                        <UserProfile
                            user={user}/>
                    )
                })}
            </div>
        )
    }
}


export default UserProfileList;

Project Name} / src / index.js

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

ReactDOM.render(
  <UserProfileList/>,
  document.getElementById('root')
);
reportWebVitals();
profile
UDR Branding Manager

0개의 댓글