의류 상품 목록을 조회하기 위한 페이지와 컴포넌트들을 구현하였다.

앞으로 각 상품 카테고리 별로 페이지가 있어야 하고  각각 다른 상품 데이터를 조회해야 하기 때문에

페이지 컴포넌트를 상품 카테고리 개수만큼 만들 것이다.

그리고 상품 아이템을 나열해 주는 ul, li태그의 역할을 하는 컴포넌트들은 모든 카테고리 페이지에서 공통적으로 사용되기에 컴포넌트 하나를 만들어서 재사용해 줄 것이다.

 

의류 상품 페이지 구현

src/common/type/products.ts

export type Product = {
  category: string;
  description: string;
  id: string;
  image: string;
  options: string[];
  price: number;
  title: string;
};

// state
export type ProductData = Product[] | undefined;

// map 돌릴 state
export type ProductItems = {
  products: Product[] | undefined;
};

// 프로덕트 카드 props
export type Props = {
  product: Product;
};

의류 상품 페이지와 Products, ProductCard 컴포넌트에 쓰일 타입을 products.ts 파일에 정의해 두었다

 

src/clothes/page/Clothes.tsx

import React, { useEffect, useState } from 'react';
import { Product, ProductData } from '../../common/types/products';
import Products from '../../common/components/Products';

const Clothes: React.FC = () => {
  const [products, setProducts] = useState<ProductData>();
  useEffect(() => {
    setProducts(data);
  }, []);
  return <Products products={products} />;
};
export default Clothes;

Clothes 컴포넌트에서 상품 데이터를 props로 전달해 주었다.

 

src/common/components/products.tsx

import React from 'react';
import styled from 'styled-components';
import { ProductItems } from '../types/products';
import ProductCard from './ProductCard';
const Products: React.FC<ProductItems> = ({ products }) => {
  return (
    <ProductList>
      {products?.map(product => (
        <ProductCard key={product.id} product={product} />
      ))}
    </ProductList>
  );
};

const ProductList = styled.ul`
  display: grid;
  padding: 16px 24px;
  grid-template-columns: repeat(4, 1fr);
  gap: 16px;
`;

Products 컴포넌트에서는 받아온 props로 받아온 상품 data배열을 map으로 돌려 배열에 있는 항목들을 ProductCard컴포넌트로 전달해주게 하였다.

 

src/common/components/productCard.tsx

import React from 'react';
import styled from 'styled-components';
import { Props } from '../types/products';
const ProductCard: React.FC<Props> = ({
  product: { category, image, price, title },
}) => {
  return (
    <Card>
      <img src={image} alt={title} />
      <div>
        <h3>{title}</h3>
        <p>{`₩${price}`}</p>
      </div>
      <p>{category}</p>
    </Card>
  );
};

export default ProductCard;

const Card = styled.li`
  & img {
    width: 100%;
  }
  cursor: pointer;
`;

props로 전달 받은 상품 항목을 ProductCard 컴포넌트로 렌더링 해주었다.

 

구현 결과

이제 앞으로 위와 같은 방식으로 다른 상품 페이지도 구현할 예정이다.

+ Recent posts