[React] 컴포넌트 합성

2022. 10. 21. 15:27·React/기능
반응형

React 하면 많은 것이 떠오르겠지만 컴포넌트, 재사용성 등의 키워드가 가장 먼저 떠오른다. 

리액트에서는 props를 통해서 컴포넌트에 새로운 엘리먼트나 컴포넌트를 추가하는 것이 가능하다.

 

이것을 컴포넌트 합성이라고 부른다.

 

그러면 내부의 디자인이 다른 UI에서도 쉽게 재사용할 수 있는 컴포넌트를 만들 수 있다. 

최강 그림판

다음과 같은 디자인이 있다고 생각해보자 

노란색 박스 영역이 조금 형식이 다른데, 위에는 보라색 버튼과, 녹색 내용이 있으며, 

아래는 버튼은 없고, 갈색 내용이 있다. 

 

이것을 위해서 모든 내용을 매개변수로 받기에는 노란색 박스가 관리해야할 매개변수가 

너무 많아진다. 

( 위 레이아웃까지야 괜찮다고 하더라도 더 큰 형식이면?! )

 

이걸 이제 React로 한번 만들어보자 

interface Props {}

const ProductPresenter = ({}: Props) => {
  const productUpList = [
    { img: '#', skyblue: '~~~~ 이것저것', green: '10시간 전' },
    { img: '#', skyblue: '~~~~ 이것저것', green: '10시간 전' },
    { img: '#', skyblue: '~~~~ 이것저것', green: '10시간 전' },
    { img: '#', skyblue: '~~~~ 이것저것', green: '10시간 전' },
    { img: '#', skyblue: '~~~~ 이것저것', green: '10시간 전' },
    { img: '#', skyblue: '~~~~ 이것저것', green: '10시간 전' },
  ];

  const productDownList = [
    { img: '#', skyblue: '~~~~ 이것저것', brown: '이 이야기는 ....' },
    { img: '#', skyblue: '~~~~ 이것저것', brown: '이 이야기는 ....' },
    { img: '#', skyblue: '~~~~ 이것저것', brown: '이 이야기는 ....' },
    { img: '#', skyblue: '~~~~ 이것저것', brown: '이 이야기는 ....' },
    { img: '#', skyblue: '~~~~ 이것저것', brown: '이 이야기는 ....' },
    { img: '#', skyblue: '~~~~ 이것저것', brown: '이 이야기는 ....' },
  ];

  return (
    <div>
      <ProductListPresenter productList={productUpList} isPurpleButton={true} />
      <ProductListPresenter productList={productDownList} isPurpleButton={false} />
    </div>
  );
};

먼저 최상단 검은색 박스이다. 

 

productUpList와 productDownList가 각각 속성이 다른것을 확인할 수 있다. 

하지만 ProductListPresenter라는 같은 컴포넌트에 매개변수를 넣어주고 있다.

 

const ProductListPresenter = ({
  productList,
  isPurpleButton,
}: {
  productList: {
    img: string;
    skyblue?: string;
    green?: string;
    brown?: string;
  }[];

  isPurpleButton: boolean;
  //
}) => {
  return (
    <div style={{ border: '1px solid red', padding: '10px', margin: ' 10px' }}>
      {productList.map((item: { img: string; skyblue?: string; green?: string; brown?: string }) => {
        return (
          <ProductItemPresenter
            productItem={item}
            detail={<p>{item.green ? <span>{item.green}</span> : item.brown ? item.brown : 'qwdqwd'}</p>}
          >
            {isPurpleButton && <button>버튼</button>}
          </ProductItemPresenter>
        );
      })}
    </div>
  );
};

 

ProductListPresenter에서는 ProductItemPresenter에게 children으로 

{isPurpleButton && <button>버튼</button>}

isPurpleButton에 따라 Element를 넘겨주고 있다. 

또한 detail에서도 내부 속성인 green과 brown에 따라 다르게 랜더링해주고 있다. 

 

const ProductItemPresenter = ({
  productItem,
  detail,
  children,
}: {
  productItem: {
    img: string;
    skyblue?: string;
  };
  detail: JSX.Element;
  children: JSX.Element | false;
}) => {
  return (
    <div style={{ display: 'flex', justifyContent: 'space-between', border: '1px solid yellow', margin: ' 10px' }}>
      <div>
        <img src={productItem.img} />
      </div>
      <div>
        <p>{productItem.skyblue}</p>
        <p>{detail}</p>
      </div>

      {children}
    </div>
  );
};

마지막으로 노란색 박스에서는 부모컴포넌트에서 받은 children과 detail을 화면에 렌더링 해주고있다. 

 

이렇게하면 다른 디자인의 리스트를 하나의 컴포넌트로 쉽게 재사용이 가능하다. 

컴포넌트를 만들 때 단순하게 분리하는 것이 아닌 필요에 따라 합성을 통해서 재사용성이 높은 

컴포넌트를 만드는 것이 중요한 것 같다. 

 

결과물

이해를 위해서 작성한 코드라서 흉측한 결과물이 나왔다 .... ㅋㅋ

반응형
저작자표시 비영리 변경금지 (새창열림)

'React > 기능' 카테고리의 다른 글

[React] useRef 그리고 useState  (1) 2022.10.26
[React] Map을 State로 사용하기  (0) 2022.10.25
[React] react-router-dom 사용하기  (1) 2022.10.05
[React] useLayoutEffect  (0) 2022.02.08
[React] useRef  (0) 2022.02.08
'React/기능' 카테고리의 다른 글
  • [React] useRef 그리고 useState
  • [React] Map을 State로 사용하기
  • [React] react-router-dom 사용하기
  • [React] useLayoutEffect
잉여개발자
잉여개발자
풀스택 개발자를 목표로 잉여롭게 개발 공부도 하면서 다양한 취미 생활도 즐기고 있는 잉여 개발자입니다.
  • 잉여개발자
    잉여로운 개발일지
    잉여개발자
    • 분류 전체보기 (789)
      • 개발정보 (36)
      • 개발환경 (7)
      • 개발생활 (19)
      • React (141)
        • 이론 (23)
        • 기능 (12)
        • 실험실 (88)
        • 버그 (6)
        • 패스트캠퍼스 (9)
        • Npm (3)
      • React Native (28)
        • 공통 (6)
        • TypeScript (3)
        • JavaScript (18)
        • 버그 (1)
      • Next.js (30)
        • 이론 (13)
        • 실험실 (13)
        • 버그 (3)
      • Web (35)
      • 알고리즘 (202)
        • 풀이 힌트 (39)
      • JavaScript (47)
      • TypeScript (29)
        • 기초 (27)
        • 실험실 (2)
      • Node.js (13)
        • 이론 (0)
        • 기능 (3)
        • 실험실 (9)
        • 버그 (1)
      • 도커 (4)
      • CCNA (22)
        • 이론 (4)
        • 문제 (18)
      • 취미생활 (167)
        • 잉여로운 칵테일 (2)
        • 잉여의 식물키우기 (130)
        • 잉여로운 여행기 (11)
        • 잉여의 제2외국어 (21)
        • 잉여로운 책장 (2)
      • Java (1)
        • Java의 정석 (1)
      • 꿀팁 공유 (3)
  • 태그

    react
    자바스크립트
    타입스크립트
    Node.js
    next.js
    프로그래머스
    Babel
    다이소
    리얼클래스
    webpack
    바질
    바질 키우기
    CCNA
    리액트
    네이버 부스트캠프
    영어독학
    식물
    Docker
    typescript
    덤프
    영어회화
    리얼학습일기
    타일러영어
    CSS
    ReactNative
    알고리즘
    ChatGPT
    javascript
    네트워크
    redux
  • hELLO· Designed By정상우.v4.10.1
잉여개발자
[React] 컴포넌트 합성
상단으로

티스토리툴바