List
컴포넌트는 배열 데이터를 출력하는 역할을 담당하며, items
에 배열 데이터를 넘겨주고, renderItem
에 렌더링 로직을 주입하는 방식으로 컴포넌트로서 명시적으로 사용할 수 있게 설계했습니다.
interface Props<T> {
items: T[];
renderItem: (item: T) => ReactNode;
}
const list = [
{
id: 1,
title: 'title1',
},
{
id: 2,
title: 'title2',
},
]
export default function Example() {
return (
<List items={list} renderItem={(item) => (
<div key={item.id}>{item.title}</div>
)}/>
)
}
Image
컴포넌트는 이미지를 렌더링하는 역할을 담당합니다.
이미지 경로, 크기, 그리고 선택적으로 borderRadius
를 받아 사이즈에 맞게 cover 모드로 중앙에 배치되도록 구현했습니다.
type Props = {
url: string;
size: {
width: string;
height: string;
};
borderRadius?: string;
} & HTMLAttributes<HTMLDivElement>;
import { Image } from '@components/common';
export default function Example() {
return (
<Image
url="<https://kakao.com>"
borderRadius="8px"
size={{
width: '350px',
height: '275px',
}}
/>
);
}
메인 페이지의 구인/구직 리스트를 표시하는 RecruitmentCard
를 합성 패턴을 사용하여 구현했습니다. 합성 패턴을 사용한 이유는 향후 변경사항이 발생할 경우, 유연하게 처리할 수 있도록 하기 위함입니다.
type Props = {
recruitment: RecruitmentItem;
children: ReactNode;
};
export default function RecruitmentCard({ recruitment, children }: Props) {
return (
<RecruitmentCardContextProvider recruitment={recruitment}>
<Card
borderColor="white"
css={[
responsiveStyle({
default: {
padding: '24px',
cursor: 'pointer',
},
mobile: {
padding: '16px',
},
}),
bounceAnimation,
]}
>
{children}
</Card>
</RecruitmentCardContextProvider>
);
}
RecruitmentCard.Title = Title;
RecruitmentCard.Button = Button;
RecruitmentCard.CompanyName = CompanyName;
RecruitmentCard.CompanyImage = CompanyImage;
RecruitmentCard.Detail = Detail;
RecruitmentCard.Salary = Salary;