🧑🎨: 디자이너 💻: 프론트엔드
위 컴포넌트에 대한 설명
메뉴
에 대한 정보가 담겨있는 카드메뉴
뿐만 아니라 추후에 레시피
가 올수도 있습니다.가게
에 대한 정보가 담겨있는 카드가게
뿐만 아니라 추후에 음식 리뷰
가 올수도 있습니다.🧑🎨의 말을 고려했을때 어떤 방식으로 컴포넌트를 개발해야할까?
<Card>
컴포넌트 하나만 만든다.컴포넌트 하나를 만들어서 props로 분기처리한다.
그렇다면 위 사진과 같은 컴포넌트들을 만들기 위해서는 총 몇개의 props
가 필요할까??
width
: 가로 (string)height
: 세로 (string)caption
: 캡션 (string)src
: 이미지의 src (string)alt
: 이미지 태그의 alt (string)variant
: Body 분기처리를 위한 변수 (string)body
: Body에 들어갈 요소들 (array)export default function Home(props: CardComponentProps){
return (
<Card
width="130px"
height="130px"
caption="Tag"
src="<https://google.co.kr/image/ASDFA12>"
alt="메뉴"
variant="menu"
body={['Headline4', 'Body3']}>
</Card>
)
}
이렇게? 아니면 Body
자체를 외부에서 주입해 children
으로 받아 사용하는 아래 형태로 만들까??
export default function Home(props: CardComponentProps){
return (
<Card
width="130px"
height="130px"
caption="Tag"
src="<https://google.co.kr/image/ASDFA12>"
alt="메뉴">
<div style={{padding: '0 4px 0 4px'}}>
<h4 style ={{padidng: '0 4px 0 4px'}}>Headline4</h4>
<p style ={{padidng: '0 4px 0 4px'}} >Body3</p>
</div>
)
}
해당 방법은 제가 처음 구현할때 시도한 방법이다.
해당 방법을 사용하지 않기로 한 이유
모양이 너무 다르기때문에, 모델이 다르기때문에 따로 만들겠다!
위와 같은 방법이라면 컴포넌트 각각의 네이밍은 어떻게 해야할까?
<MenuCard>
<StoreCard>
목적성을 가진 네이밍
을 사용한다고 해보자
만약 <MenuCard>
와 똑같이 생긴 레시피
를 나타내는 카드가 추가된다면 어떻게 해야할까?<RecipeCard>
를 추가 해야할까?
<ColumnBodyCard>
<RowBodyCard>
모양의 특징을 가진 네이밍
을 사용한다고 해보자
만약 Body의 모양이 네이밍 하기 애매한 디자인이 나온다면 어떻게 해야할까?
만약 같은 모양의 카드가 자주 등장한다면 body를 매번 작성해서 넘겨줘야하나?
<ImageCaptionHeadlineBodyCard>
<ImageDateLikebuttonCard>
가지고 있는 요소에 대한 네이밍
을 사용한다고 해보자
만약 왼쪽 카드에서 아래에 <q>
가 추가된다면 <ImageCaptionHeadlineBodyQCard>
를 추가해야할까?
만약 왼쪽 카드에서 Headline4가 아니라 Headline2를 가진 카드가 추가된다면 어떻게 해야할까?
해당 방법은 주변 지인들에게 물어보았을때 가장 많이 나온 방법이다.
내가 해당 방법을 사용하지 않기로 한 이유
공통화가 가능한 부분은 하나로 만들고 나머지 부분은 children을 활용해 목적성이 있는 컴포넌트를 만들자
export default function ImageWithCaption(props: ImageProps) {
return (
<ImageFigure size={props.size}>
<Image src={props.src} alt={props.alt} fill />
<ImageCaption size={props.size}>{props.caption}</ImageCaption>
</ImageFigure>
);
}
export default function Card(props: CardProps) {
return (
<Layout size={props.size}>
<ImageWithCaption
src={props.data.src}
caption={props.data.caption}
alt={props.data.alt}
size={props.size}
/>
<CardBody>{props.children}</CardBody>
</Layout>
);
}
export default function MenuCard(props: CardComponentProps) {
return (
<Card data={props.data} size="137px">
<Headline2>{props.headline}</Headline2>
<Body2>{props.body}</Body2>
</Card>
);
}
<MenuCard
data={{
src: '<https://image.msscdn.net/images/style/list/l_3_2023080717404200000013917.jpg>',
alt: '카드',
caption: 'Tag',
}}
headline={'Headline4'}
body={'Body2'}
/>
만약 새로운 카드 컴포넌트가 생기면 <Card>
컴포넌트로 감싸 body만 추가해주면 쉽게 만들 수 있다.
위 방법을 시도해본 후기
카드 컴포넌트에 컴파운드 패턴을 시도해본 결과 카드 컴포넌트를 page 단위에서
사용하기 위해서 아래와 같이 만들어보았다.
<Card>
<Card.Recipe
imageProps={data}>
</Card>
이 방법도 괜찮은 방법이긴 하지만 <Card>
라는 Context를 항상 가져와서 사용하다보니 코드가 길어지고, 가독성이 좀 떨어지는 느낌을 받았다.
그래서 나는 Card라는 폴더 아래에 <CardLayout>
로 Card를 추상화 하고 <RecipeCard>
라는 파일을 만들어 <CardLayout>
을 활용하는 방법을 선택했다.
//recipeCard.tsx
const RecipeCard = () => {
return (
<CardLayout data={props.data} size="228px">
<Layout>
<Subtitle2>{props.callout}</Subtitle2>
<button>
<AiOutlineHeart />
</button>
</Layout>
</CardLayout> )
}
//app.tsx
<RecipeCard imageProps={data}/>
협업 과정에서 추상화 기준잡는게 제일 어려운것 같다..
팀원과 고심끝에 함께 선택한 방법이지만 또 다른 사람의 의견이 궁금하다.
이전글: 사이드 프로젝트 개발 과정 - (기술 스택 선정 및 세팅)
다음글: 사이드 프로젝트 개발 과정 - (파일구조 잡기)