-
[ReactJS] Composition vs InheritanceProgramming/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