Composition
Composition 사용 기법
Containment
BOX형태의 컴포넌트는 자신의 하위 컴포넌트를 미리 알 수 없다
children이라는 prop을 사용해서 조합한다
여러개의 children이 필요한 경우는?
left와 right등으로 나누어서 사용한다.
Specialization
전문화, 특수화
기존의 객체지향 언어에서는 상속을 사용하여 구현하였다.
React에선 Composition을 사용하여 Specialization을 구현한다.
Containment & Specialization
Inheritance
다른 컴포넌트로부터 상속 받아 새로운 컴포넌트를 만드는 것
즉, 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();