[웹 개발] React 기초 (13)

프로타쿠·2024년 7월 6일

웹 개발

목록 보기
17/21

Composition

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

리액트를 개발하면서, 컴포넌트를 어떻게 합치는지에 따라 코드 가독성, 렌더링 성능, 유지보수 난이도 등이 변한다.

Containment

Container 같은 느낌으로, 하위 컴포넌트를 포함하는 형태의 합성 방법이다. 예를 들면, Sidebar, Dialog 같은 Box 형태의 컴포넌트는 자신의 하위 컴포넌트를 미리 알 수 없다. 이런 경우에 Containment를 활용해 Composition을 구현한다.

function FancyBorder(props) {
  return (
    <div className={'FancyBorder FancyBorder-' + props.color}>
      // 해당 prop는 리액트에서 기본적으로 제공하는 것이다.
      {props.children}
    </div>
  );
}

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

만약 Children이 여러 개 필요하다면?

props에 따로 정의해서 사용하면 된다.

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

범용적인 컴포넌트를 구체화하여 세부적인 컴포넌트로 따로 구분하는 것
Ex) WelcomeDialog는 Dialog의 일종이다.

function FancyBorder(props) {
  return (
    <div className={'FancyBorder FancyBorder-' + props.color}>
      {props.children}
    </div>
  );
}

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 FancyBorder(props) {
  return (
    <div className={'FancyBorder FancyBorder-' + props.color}>
      {props.children}
    </div>
  );
}

function Dialog(props) {
  return (
    <FancyBorder color="blue">
      <h1 className="Dialog-title">
        {props.title}
      </h1>
      <p className="Dialog-message">
        {props.message}
      </p>
      
      // Containement
      {props.children}
    </FancyBorder>
  );
}

// Specialization
function SignUpDialog(props) {
  const [nickname, setNickname] = useState('');
  
  const handleChange = (event) => {
    setNickname(event.target.value);
  };
  
  const handleSignUp = () => {
    alert(`어서 오세요, ${nickname}님!`);
  };
  
  return (
    <Dialog
      title="화성 탐사 프로그램"
      message="닉네임을 입력해주세요.">
      <input
        value={nickname}
        onChange={handleChange} />
      <button onClick={handleSignUp}>
        가입하기
      </button>
    </Dialog>
  );
}

Inheritance

자식 컴포넌트가 부모 컴포넌트의 속성을 그대로 물려받아 사용하는 것

그런데 왜 안 쓸까?

Meta에서 연구한 결과, 그리 좋은 사용처를 찾지 못했다. 그래서 위의 Composition으로 충분한 듯




Referance

[인프런] 처음 만난 리액트(React) 강의 - 소플

profile
안녕하세요! 프로타쿠입니다

0개의 댓글