- 쿠팡 상품 페이지를 구현
- 공통된 UI들을 컴포넌트로 추출
- 상태 관리 및 비즈니스 로직에 집중
- 화면을 어느 단위로 나누는 것이 효율적일지
- 가독성 좋은 JSX 작성
- 디렉토리 구조를 고려
✨ 이번 챌린지의 목표는 하나의 페이지를 데이터와 상태를 기준으로 나누어보는 것입니다.
페이지 내에서 2번 이상 사용되는 요소를 컴포넌트로 추출했습니다.
<StartRating />
average
평균값을 받아서 별점으로 표시하는 컴포넌트 입니다.
<Price />
<Price />
<Price size='sm' />
price의 size 기본값은 md 이고 원가와 할인율을 보여줍니다.
사이즈가 md일 때, 원가와 할인율을 꼭 작성하도록 하고싶은데 어떻게 타입을 지정해야할 지 몰라 더 찾아보고 수정하고 싶습니다.
<RocketBage />
type
타입에 따라 배지 이미지를 보여주는 컴포넌트 입니다.
로켓프레쉬나 로켓직구도 이후에 추가할 수 있게 컴포넌트로 분리하면 재사용성이 높을 것 같습니다.
vendorItemPage에서 사용하는 api는 4개로
가 있었습니다. 이 데이터를 기준으로 큰 구조를 section으로 나눴습니다.
export default function VendoritemPage() {
const { item, details, breadcrumble, otherItems } = useProductMock();
return (
<Main>
<Breadcrumble breadcrumble={breadcrumble} />
<Item item={item} />
<OtherItems otherItems={otherItems} />
<Details details={details} />
</Main>
);
}
1회차 때 고민했던 api 리팩토링 방식을 사용했으면 좋았겠지만 시간이 부족할 것 같다고 생각해서 일단 데이터만 빨리 받아올 수 있도록 useProductMock이라는 훅으로 데이터를 받아왔습니다. 임시적인 로직이라 mock이라고 이름붙였고 수정을 빨리 하고싶습니다..
왼쪽은 이미지에 대한 정보를 담고 있고 오른쪽은 주문에 필요한 정보를 담고 있어서 ItemImages, ItemInfo 로 구역을 나눴습니다.
const Item = ({ item }: IProps) => {
if (!item) return <p>item 로딩중...</p>;
return (
<section>
<ItemImages />
<ItemInfo />
</section>
);
};
여기에선 다루는 데이터도 많고 요소가 많아 생각보다 시간이 들었습니다.
최대한 심플하게 작성하고 싶었고 추상화의 정도를 비슷하게 맞추는 것을 고려하면서 작성했습니다.
const ItemInfo = ({}: IProps) => {
return (
<Wrapper>
<div className='info-header'>
<BlueLink to='/apple' title='Apple' />
<Title title='Apple 아이폰 13 mini 자급제' />
<StarRating />
<BlueLink to='/review' title='13,130개 상품평' />
</div>
<div className='info-price'>
<Price
price={902200}
orignPrice={950000}
discountRate={5}
unit={'원'}
/>
<RocketBage type='ROCKET' />
</div>
<div className='info-shipping'>
<p>무료배송</p>
<Radio
title='내일(목) 7/21'
description='(23시간 57분 내 주문 시 / 서울⋅경기 기준)'
/>
<Radio
title='내일(수) 7/27 새벽 7시 전 '
description='(오후 4시 30분 전 주문 시 / 서울⋅경기 기준)'
/>
</div>
<div className='info-insurance'>
<InsuranceCheck
title='AppleCare+'
price={179000}
description='우발적인 손상에 대한 보상을 받아보세요.'
/>
</div>
<div className='info-submit'>
<CountInput />
<CartBtn />
<BuyBtn />
</div>
</Wrapper>
);
};
회고록 작성하려고 기존 참고 사이트 들어가니 그새 품절되어서 다른 상품페이지를 캡쳐했습니다. 배송을 선택할 수 있는 radio input 부분이 없어서 아쉽습니다. 그 부분 데이터가 서버에서 html tag로 데이터를 주는데 어떻게 받아야하는지 몰라 일단 정적으로 만들었습니다.
전부 완성하지 못해 아쉬움이 남지만 제출후에 수정을 할 예정입니다.
가독성 좋은 jsx를 작성하기 위해 이번엔 이 영상 | 토스ㅣSLASH 21 - 실무에서 바로 쓰는 Frontend Clean Code에서 추천하는 대로 작성하려고 노력했습니다. 더러울 때 일단 뭉쳐두는 것이 나중에 리팩도링할 때 도움이 된다고 생각해서 기준 없이 일단 뭉쳤었는데, 여기서는 핵심정보는 밖에서 전달받고 몰라도 되는 세부디테일은 숨기는 것이 코드파악에 도움이 된다고 알려주어 이 부분을 많이 고민했습니다.
그리고 이렇게 세부디테일을 숨긴 추상화된 컴포넌트와 아닌 컴포넌트가 섞여있으면 코드를 읽을 때 흐름이 끊길 수 있다는 것도 알게 되어 추상화수준도 비슷하게 맞추려고 했습니다.
썻다 지웠다 한 코드가 많아 진도가 느려서 아쉽긴 했지만 가독성 좋은 jsx를 깊게 고민해볼 수 있어서 좋은 경험이었고
그렇게 고민했는데도 아직 완성도가 떨어지는 걸 보면 배울점이 많다는 것도 느낍니다 😂
3회차 동안 배운 부분을 개인 포트폴리오에 적용해보면서 3주를 보내고 다음 4회차도 더 잘하도록 노력하겠습니다!