https://reactjs.org/docs/composition-vs-inheritance.html - 번역 글
React는 강력한 구성 모델을 가지고 있으며 상속 대신 구성을 사용하여 컴포넌트 사이의 코드를 재활용하는 걸 권장합니다.
이 섹션에서는 React를 처음 사용하는 개발자가 상속을 위해 종종 도달하는 몇 가지 문제를 살펴보고 구성을 통해 문제를 해결할 수있는 방법을 보여줍니다.
일부 컴포넌트는 자식를 미리 알지 못합니다. 이는 일반적으로 박스로 사용되는 Sidebar
또는 Dialog
같은 컴포넌트가 그렇습니다.
이러한 컴포넌트는 특수한 children prop
을 사용하여 자식 요소를 출력에 직접 전달하는 것이 좋습니다.
function FancyBorder(props) {
return (
<div className={'FancyBorder FancyBorder-' + props.color}>
{props.children}
</div>
);
}
이렇게하면 JSX
를 중첩하여 다른 컴포넌트가 임의의 자식을 전달할 수 있습니다.
function WelcomeDialog() {
return (
<FancyBorder color="blue">
<h1 className="Dialog-title">
Welcome
</h1>
<p className="Dialog-message">
Thank you for visiting our spacecraft!
</p>
</FancyBorder>
);
}
<FancyBorder>
컴포넌트 내부에 작성된 JSX
는 모두 FancyBorder
컴포넌트의 children
로 전달됩니다. FancyBrorder
는 {props.children}
를 <div>
안에 렌더링하므로 전달된 요소는 최종 출력에 나타납니다.
자주 사용되지는 않지만 구성 요소에 여러 개의 구멍이 필요할 수 있습니다. 이런 경우에는 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() {
return (
<SplitPane
left={
<Contacts />
}
right={
<Chat />
} />
);
}
<Contacts />
나 <Chat />
같은 React 요소는 단순 객체로 어떤 다른 데이터든 props
를 통해 전달할 수 있습니다. 이것은 다른(Vue)
라이브러리의 slots(슬롯)
를 생각나게할 수 있지만 React에서 props
로 전달할 수 있는 것에는 제한이 없습니다.
가끔 컴포넌트가 다른 컴포넌트의 특수한 경우 (special case) 라고 생각합니다. 예를 들어 WelcomeDialog
는 Dialog
의 특수한 경우라고 말할 수 있습니다.
React에서는 콤포지션 (composer
)을 사용합니다. 더 구체적인 컴포넌트가 범용구성 요소를 렌더링하고이를 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() {
return (
<Dialog
title="Welcome"
message="Thank you for visiting our spacecraft!" />
);
}
컴포지션은 클래스로 정의 된 컴포넌트에도 똑같이 적용됩니다.
function Dialog(props) {
return (
<FancyBorder color="blue">
<h1 className="Dialog-title">
{props.title}
</h1>
<p className="Dialog-message">
{props.message}
</p>
{props.children}
</FancyBorder>
);
}
class SignUpDialog extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
this.handleSignUp = this.handleSignUp.bind(this);
this.state = {login: ''};
}
render() {
return (
<Dialog title="Mars Exploration Program"
message="How should we refer to you?">
<input value={this.state.login}
onChange={this.handleChange} />
<button onClick={this.handleSignUp}>
Sign Me Up!
</button>
</Dialog>
);
}
handleChange(e) {
this.setState({login: e.target.value});
}
handleSignUp() {
alert(`Welcome aboard, ${this.state.login}!`);
}
}
Facebook
에서는 수천 개의 구성 요소에서 React를 사용하며 구성 상속 계층 구조를 만드는 것이 권장되는 사용 사례는 찾지 못했습니다.
props
와 구성은 명시적이며 안전한 방법으로 컴포넌트의 모양과 동작을 커스터마이징하는 데 필요한 모든 유연성을 제공합니다. 컴포넌트는 기본 값, React
요소 함수를 비롯한 임의의 props
를 수용할 수 있습니다.
컴포넌트 간 UI
가 아닌 기능을 재사용하려면 별도의 자바스크립트 모듈로 추출하는 것이 좋습니다. 컴포넌트는 이를 가져오거나 함수, 객체 또는 클래스를 확장하지 않고 사용할 수 있습니다.