2차 프로젝트

이청원·2023년 9월 30일
0


2차 프로젝트 클론 코딩 구현은 와이즐리 홈페이지이다.

프로덕트 파일

//product.js
import React, { useEffect, useState } from 'react';
import { useParams } from 'react-router-dom';
import Goods from '../../components/Goods/Goods';
import './Product.scss';

const Product = () => {
  const [data, setData] = useState({});
  const params = useParams();
  useEffect(() => {
    fetch(`/data/product/${params.category}.json`)
      .then((res) => {
        return res.json();
      })
      .then((result) => {
        setData(result);
      });
  }, [params.category]);

  if (!Object.keys(data).length > 0) return null;

  return (
    <div className="product">
      <div className="goodsContainer">
        <Goods data={data} />
      </div>
    </div>
  );
};

export default Product;

디테일 파일

import React, { useEffect, useState } from 'react';
import './Details.scss';
import Count from '../../components/Count/Count';
import Delivery from '../../components/Delivery/Delivery';
import { useNavigate, useParams } from 'react-router-dom';

const Details = () => {
  const [count, setCount] = useState(1);
  const [product, setProduct] = useState({});
  const navigate = useNavigate();
  const params = useParams();

  const basketClcik = () => {
    navigate('/basket');
  };

  useEffect(() => {
    const productId = Number(params.productId);

    fetch('/data/product/all.json')
      .then((res) => {
        return res.json();
      })
      .then((data) => {
        const list = data.list;
        for (let i = 0; i < list.length; i++) {
          if (list[i].id === productId) {
            setProduct(list[i]);
          }
        }
      });
  }, [params.productId]);

  return (
    <div className="details">
      <div className="container">
        <div className="imgBox">
          <img src={product.img} alt="제품이미지" />
        </div>

        <div className="decision">
          <p className="brandName">와이들리 면도기</p>

          <div className="title">
            <h1>{product.title}</h1>
            <i className="fa-regular fa-heart" />
          </div>

          <p className="assistant">{product.Description}</p>
          <span className="price">
            {product.price?.toLocaleString('ko-KR')}</span>

          <Count
            count={count}
            setCount={setCount}
            price={product.price}
            title={product.title}
          />

          <Delivery />

          <div>
            <button className="basket" onClick={basketClcik}>
              장바구니
            </button>
          </div>
        </div>
      </div>
    </div>
  );
};

export default Details;

라우터 파일

import React from 'react';
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import Login from './pages/Login/Login';
import Main from './pages/Main/Main';
import Nav from './components/Nav/Nav';
import Product from './pages/Product/Product';
import Details from './pages/Details/Details';
import Footer from './components/Footer/Footer';
import Basket from './pages/Basket/Basket';

const Router = () => {
  return (
    <BrowserRouter>
      <Nav />
      <Routes>
        <Route path="/" element={<Login />} />
        <Route path="/main" element={<Main />} />
        <Route path="/product/:category" element={<Product />} />
        <Route path="/details/:productId" element={<Details />} />
        <Route path="/basket" element={<Basket />} />
      </Routes>
      <Footer />
    </BrowserRouter>
  );
};

export default Router;

카운트 파일

import React from 'react';
import './Count.scss';
const Count = (props) => {
  const { count, setCount, price, title } = props;
  const minus = () => {
    if (count > 1) {
      setCount(count - 1);
    }
  };

  return (
    <>
      <div className="countAll">
        <p>{title}</p>
        <div>
          <div className="countBox">
            <span>{(price * count).toLocaleString('ko-KR')}</span>
            <button
              onClick={() => {
                setCount(count + 1);
              }}
            >
              +
            </button>
            <span>{count}</span>
            <button onClick={minus}>-</button>
          </div>
        </div>
      </div>
      <div className="totalPriceBox">
        <span>총 금액</span>
        <span className="totalPrice">
          {(price * count).toLocaleString('ko-KR')}
        </span>
      </div>
    </>
  );
};

export default Count;

굿즈 파일

import React from 'react';
import { useNavigate } from 'react-router-dom';
import './Goods.scss';

const Goods = (props) => {
  const { data } = props;

  const navigate = useNavigate();

  const showDetail = (id) => {
    navigate(`/details/${id}`);
  };

  return (
    <div>
      <h1>{data.category}</h1>
      <div className="total">
        <p>{`${data.total}`}</p>

        <select className="select">
          <option>-정렬 방식-</option>
          <option>신상품</option>
          <option>낮은가격</option>
          <option>높은가격</option>
        </select>
      </div>
      <div className="goods">
        {data.list.map((item) => {
          return (
            <div className="goodsProduct" key={item.id}>
              <img
                className="imgSize"
                src={`${item.img}`}
                alt="상품이미지"
                onClick={() => showDetail(item.id)}
              />
              <span className="price">
                {`${item.price.toLocaleString('ko-KR')}`}
              </span>
              <p
                className="title"
                onClick={() => showDetail(item.id)}
              >{`${item.title}`}</p>
              <span className="Description">{`${item.Description}`}</span>
            </div>
          );
        })}
      </div>
    </div>
  );
};

export default Goods;

딜리버리 파일

import React from 'react';
import './Delivery.scss';

const Delivery = () => {
  return (
    <div className="deliveryBox">
      <div className="a">4만원 이상 구매 시 무료배송</div>
      <div className="deliveryPrice">
        <div className="d">배송비</div>
        <div className="deliverySmallBox">
          <span className="b">무료배송까지남은금액</span>
          <span className="c">9월 한정 혜택입니다</span>
        </div>
      </div>
    </div>
  );
};

export default Delivery;

네브 파일

import React, { useState } from 'react';
import { Link } from 'react-router-dom';
import Dropdown from './component/Dropdown';
import './Nav.scss';

const Nav = () => {
  const [listBtn, setListBtn] = useState(false);

  return (
    <nav className="nav">
      <p className="event">
        <b>[신규혜택]</b> 1만원 쿠폰팩 증정
      </p>
      <header>
        <div className="inner-wrap">
          <div>
            <Link to="/main" className="mainTitle">
              widely
            </Link>
            <span>최고의 가성비가 아니면 팔지않습니다.</span>
          </div>
          <div>
            <Link className="loginLink" to="/login">
              가입/로그인
            </Link>
            <span>고객센터</span>
            <span>공지사항</span>
          </div>
        </div>
      </header>
      <div className="viewList">
        <div className="inner-wrap">
          <div
            className="category"
            onMouseOver={() => setListBtn(true)}
            onMouseOut={() => setListBtn(false)}
          >
            <div className="categoryList">
              <i className="fa-solid fa-bars" />
              <button>카테고리</button>
              {listBtn ? <Dropdown setListBtn={setListBtn} /> : null}
            </div>
          </div>
          <div className="tabWrapper">
            <Link className="mainLink" to="/main"></Link>
            <span>신제품</span>
            <span>베스트</span>
            <span>와이들리 LAB</span>
          </div>
          <div className="inputI">
            <div className="glasses">
              <input type="text" />
              <i className="fa-solid fa-magnifying-glass" />
            </div>
            <i className="fa-regular fa-heart" />
            <i className="fa-solid fa-bag-shopping" />
          </div>
        </div>
      </div>
    </nav>
  );
};

export default Nav;

2차 프로젝트의 목표는 1차 프로젝트 할때보다 컴포넌트를 활용하는것이었고!
state와 props 를 조금 더 적극 적으로 활용해 보는것이다!
일주일 동안 만들어진 로직이고! 사진의 이미지를 클릭했을때 사진의 이미지의 데이터를 가지고와
상세페이지에서 제품을 보여주는 로직을 구현하였다

홈페이지를 만들면서 Router 설계 자체가 부족함을 많이 느꼇고! 쿼리스트링 동적라우팅
useSearchParams , Params 을 활용하여 경로의 명확성? 경로를 정확하게 라우터 설계를 해야할것같다. 그리고 props state를 활용 하여 클릭이벤트가 발생했을때 카운트가 올라가며 가격도 올라가는 부분을 구현하였는데 ! 개수와종합가격을 어떠한 방식으로 값을 넘겨주어 계산하는 페이지로 데이터를 이어서 넘겨주어야할지도 고민해야겠다.

useSearchParams , Params 를 활용하는방법과 이해를 높여야 프로젝트를 조금더 많이 구현할수있을거같고!! 2차프로젝트를 하면서 느낀점은 컴포넌트의 재사용 재활용이 중요하다는점이 보인다. 그리고 UI를 다 그리고난후 하나씩 컴포넌트로 빼서 작업하는 방식을 선택하였는데.. 시간이 더욱 오래걸리고 정리가 안되는 느낌을 많이 받았다. 2번 작업하는?결과를초례

팀 프로젝트를 진행하면서 기능별로 로직을 구현하거나 수정하는부분이 생겻을때마다 명확하게 git을 이용 하여 commit을 정확히 남겨야하는 부분을 깨달앗고 앞으로 일주일 남았는데
시간을 잘활용하여서 ! 최선을 다하자!

수정하고 해야하는 기능이 너무 많이 남았지만!! 욕심내지말고 하나씩 이해하면서 해보는게 중요한거같고! 프로젝트를 통해 시간관리와 티켓관리의 중요성도 느끼고잇다.

컴포넌트관리를 안하면 Rract 장점을 살리지못하는!! 1차적인 느낀점 끝!

profile
어제보다 나은 사람이 되도록 노력하자!

0개의 댓글