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차적인 느낀점 끝!