사이드 프로젝트 개발 과정 - (추상화 기준 잡기)

knh6269·2024년 5월 21일
0

ootd.zip

목록 보기
4/16
post-thumbnail

🧑‍🎨: 디자이너 💻: 프론트엔드

고민점

위 컴포넌트에 대한 설명

  • 좌측 컴포넌트: 메뉴에 대한 정보가 담겨있는 카드
    • 🧑‍🎨: 메뉴 뿐만 아니라 추후에 레시피가 올수도 있습니다.
  • 우측 컴포넌트: 가게에 대한 정보가 담겨있는 카드
    • 🧑‍🎨: 가게 뿐만 아니라 추후에 음식 리뷰가 올수도 있습니다.

🧑‍🎨의 말을 고려했을때 어떤 방식으로 컴포넌트를 개발해야할까?


어떤 방법들이 있을까 ?

1. <Card> 컴포넌트 하나만 만든다.

컴포넌트 하나를 만들어서 props로 분기처리한다.

그렇다면 위 사진과 같은 컴포넌트들을 만들기 위해서는 총 몇개의 props가 필요할까??

  1. width : 가로 (string)
  2. height : 세로 (string)
  3. caption : 캡션 (string)
  4. src : 이미지의 src (string)
  5. alt : 이미지 태그의 alt (string)
  6. variant : Body 분기처리를 위한 변수 (string)
  7. 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>
   )
}

해당 방법은 제가 처음 구현할때 시도한 방법이다.
해당 방법을 사용하지 않기로 한 이유

  • 너무 많은 props
  • 같은 모양의 카드가 자주 등장할때마다 body를 작성해 넘겨줘야 하는 시간
  • 변경사항 발생 시 variant가 매번 추가됨 -> vairant와 관련된 css의 가독성 저하

2. 각각 다른 컴포넌트로 만든다.

모양이 너무 다르기때문에, 모델이 다르기때문에 따로 만들겠다!

위와 같은 방법이라면 컴포넌트 각각의 네이밍은 어떻게 해야할까?

목적성을 가진 네이밍을 사용한다고 해보자
만약 <MenuCard>와 똑같이 생긴 레시피를 나타내는 카드가 추가된다면 어떻게 해야할까?<RecipeCard>를 추가 해야할까?

<ColumnBodyCard> <RowBodyCard>

모양의 특징을 가진 네이밍을 사용한다고 해보자
만약 Body의 모양이 네이밍 하기 애매한 디자인이 나온다면 어떻게 해야할까?
만약 같은 모양의 카드가 자주 등장한다면 body를 매번 작성해서 넘겨줘야하나?

<ImageCaptionHeadlineBodyCard> <ImageDateLikebuttonCard>

가지고 있는 요소에 대한 네이밍을 사용한다고 해보자
만약 왼쪽 카드에서 아래에 <q>가 추가된다면 <ImageCaptionHeadlineBodyQCard>를 추가해야할까?
만약 왼쪽 카드에서 Headline4가 아니라 Headline2를 가진 카드가 추가된다면 어떻게 해야할까?

해당 방법은 주변 지인들에게 물어보았을때 가장 많이 나온 방법이다.
내가 해당 방법을 사용하지 않기로 한 이유

  • 위와 같이 네이밍이 너무 애매한 문제
  • 코드의 재사용이 거의 없는 수준

3. 적절히 섞는다. (내가 고른 방법)

공통화가 가능한 부분은 하나로 만들고 나머지 부분은 children을 활용해 목적성이 있는 컴포넌트를 만들자

ImageWithCaption

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>
  );
}

Card

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>
  );
}

Home

<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}/>

정리

협업 과정에서 추상화 기준잡는게 제일 어려운것 같다..
팀원과 고심끝에 함께 선택한 방법이지만 또 다른 사람의 의견이 궁금하다.

이전글: 사이드 프로젝트 개발 과정 - (기술 스택 선정 및 세팅)
다음글: 사이드 프로젝트 개발 과정 - (파일구조 잡기)

0개의 댓글