처음 만난 리액트(React) : section 13. Composition vs Inheritance

꿀돼질래·2022년 9월 5일
0
post-thumbnail

💡 Composition 방법과 Inheritance

Composition

구성 합성

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

여러 개의 컴포넌트들을 어떻게 조합할 것인가?

Containment

Contain 담다, 포함하다

하위 컴포넌트를 포함하는 형태의 합성 방법

  • children이라는 속성을 사용해서 조합
  • Sidebar나 Dialog 같은 Box형태의 컴포넌트는 자신의 하위 컴포넌트를 미리 알 수 없음
    • 동일한 Sidebar Component를 이용하는 두 개의 쇼핑몰,
      하나는 의류 관련된 메뉴 8개, 다른 하나는 식료품과 관련된 메뉴 10개
      Sidebar Component 입장에서는 자신의 하위 컴포넌트로 어떤 것들이 올지 모름
      해당 컴포넌트를 사용하는 개발자따라 다름

children prop을 사용한 FancyBorder Component

function FancyBorder(props) {
  	return (
      	<div className={'FancyBorder FancyBorder-' + props.color}>
      		// 해당 Component에 하위 컴포넌트가 모두 children에 들어감
      		// 개발자가 직접 넣어주는 것이 아닌 리액트에서 기본적으로 제공
      		{props.children}
		</div>
	);
}
  • children이 배열로 되어 있는 이유?
    • 여러 개의 하위 컴포넌트를 가질 수 있기 때문에

FancyBorder Component 사용

function WelcomeDialog(props) {
  	return (
      	<FancyBorder color="blue">
      		// h1, p태그는 FancyBorder Component에 children 이름의 props로 전달
      		<h1 className="Dialog-tilte">
      			어서오세요
      		</h1>
      		<p className="Dialog-message">
      			우리 사이트에 방문하신 것을 환영합니다!
      		</p>
      	</FancyBorder>
    );
}

여러 개의 Children 집합이 필요한 경우는 어떻게 할까?

function SplitPane(props) {
  	return (
      	// 왼쪽 오른쪽 분할해서 보여주는 Component
      	<div className="SplitPane">
      		<div className="SplitPane-left">
      			{props.left}
			</div>
			<div className="SplitPane-right">
              	{props.right}
			</div>
		</div>
	);
}

function App(props) {
  	return (
      	// 두 개의 Props, 각각 다른 Component
      	<SplitPane
      		left={
      			<Contacts />
      		}
			right={
              	<Chats />
            }
		/>
   );
}

// 여러 개의 children 집합이 필요한 경우 별도의 props를 정의

Specialization

특수화 전문화

범용적인 개념을 구별이 되게 구체화하는 것

  • 리액트에서는 합성(Composition)을 사용하여 구현
    • 기존의 객체지향 언어에서는 상속(Inheritance)을 사용하여 Specialization을 구현
function Dialog(props) {
  	return (
      	<FancyBorder color="blue">
      		<h1 className="Dialog-title">
      			// 두 가지 props 사용
      			// 제목
      			{props.title}
			</h1>
			<p className="Dialog-message">		
              	// 메시지
              	{props.message}
			</p>
		</FancyBorder>
	);
}

function WelcomeDialog(props) {
  	return (
      	<Dialog
      		title="어서 오세요"
      		message="우리 사이트에 방문하신 것을 환영합니다!"
      	/>
    );
}

/* 범용적으로 쓸 수 있는 Component를 만들어 놓고 
이를 특수화해서 Component를 사용하는 Composition */ 

Containment와 Specialization을 같이 사용하기

  • Containment를 위해 props.children 사용
  • Specialization을 위해 직접 정의한 props 사용
function Dialog(props) {
  	return (
      	<FancyBorder color="blue">
      		<h1 className="Dialog-title">
      			{props.title}
			</h1>
			<p className="Dialog-message">		
              	{props.message}
			</p>
			// 이를 통해 하위 컴포넌트가 Dialog 하단에 렌더링
			{props.children}
		</FancyBorder>
	);
}
function SignUpDialog(props) {
  	const [nickname, setNickname] = useState('');

  	const handleChange = (event) => {
      	setNickname(event.target.value);
    }
    
    const handleSignUp = () => {
      	alert(`어서오세요. ${nickname}님!`);
    }
    
    return (
      	<Dialog
   			// Specialization
      		// Specialization을 위한 props인 title, message에 값을 넣어줌
      		title="화성 탐사 프로그램"
      		message="닉네임을 입력해 주세요.">
      	// Containment
      	// 사용자로부터 입력받고 가입을 하도록 유도하기 위해 input과 button 태그 
      	// props.children에 전달, Dialog에 표시
          <input
              value={nickname}
              onChange={handleChange} />
          <button onClick={handleSignUp}>
              가입하기
          </button>
         </Dialog>
	);
}

Inheritance

상속

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


마무리 하며..

🧠 컴포넌트를 요리조리 요리듯이 새로운 컴포넌트를 만들어보자

0개의 댓글