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 |