-
Notifications
You must be signed in to change notification settings - Fork 26
[오하영] Sprint6 #151
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: react-오하영
Are you sure you want to change the base?
[오하영] Sprint6 #151
The head ref may contain hidden characters: "react-\uC624\uD558\uC601"
Conversation
reach0908
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
미션하시느라 고생많으셨습니다!
백엔드는 별도의 레포지터리로 옮기시면 좋을 것 같습니다!
추가로 이렇게 폴더를 옮기는 경우 변경사항들이 기록되지 않는 경우가 있는데, 폴더 옮기기만 진행한 후 커밋을 한번하고 그 뒤에 파일들을 수정하시면 파일 diff가 잘 기록됩니다!
모바일에서 상단 헤더때문에 레이아웃이 깨지는 문제가 발생하고 있습니다!
| export const handleError = async (url, options = {}) => { | ||
| try { | ||
| const res = await fetch(url, options); | ||
| if (!res.ok) { | ||
| throw new Error(`HTTP error: ${res.status}`); | ||
| } | ||
| const body = await res.json(); | ||
| return body; | ||
| } catch (e) { | ||
| console.error("Failed to fetch products:", e); | ||
| throw e; | ||
| } | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[P1]
공통되는 로직을 분리한 것은 좋았으나 네이밍을 변경하면 좋을 것 같습니다.
해당 로직에서 에러만 핸들링하는 것이 아닌 fetch의 기능도 포함하고 있어 오해할 수도 있을 것 같습니다!
| }; | ||
|
|
||
| return ( | ||
| <form onSubmit={handleAddItem}> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
form 활용 좋습니다!
| <input | ||
| type="text" | ||
| value={name} | ||
| onChange={(e) => setName(e.target.value)} | ||
| placeholder="상품명을 입력해주세요" | ||
| /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[P2]
input 태그의 속성을 활용한 validation 방법에 대해서 알아보시면 좋을 것 같습니다!
| useEffect(() => { | ||
| const updatePageSize = () => { | ||
| if (window.matchMedia("(max-width: 743px)").matches) { | ||
| setPageSize(BEST_PAGE_SIZE.mobile); | ||
| } else if (window.matchMedia("(max-width: 1199px)").matches) { | ||
| setPageSize(BEST_PAGE_SIZE.tablet); | ||
| } else { | ||
| setPageSize(BEST_PAGE_SIZE.desktop); | ||
| } | ||
| }; | ||
|
|
||
| updatePageSize(); | ||
|
|
||
| window.addEventListener("resize", updatePageSize); | ||
| return () => { | ||
| window.removeEventListener("resize", updatePageSize); | ||
| }; | ||
| }, []); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[P1]
커스텀 훅으로 빼보면 좋을 것 같습니다!
| {bestItems.map((item) => ( | ||
| <div key={item.id}> | ||
| <img className={styles.img} src={defaultImg} alt={item.name} /> | ||
| <div className={styles.description}> | ||
| <div className={styles.name}>{item.name}</div> | ||
| <div className={styles.price}>{item.price}원</div> | ||
| <div className={styles.favoriteCount}> | ||
| <img src={unheartIcon} alt="좋아요 아이콘" />{" "} | ||
| {item.favoriteCount} | ||
| </div> | ||
| </div> | ||
| </div> | ||
| ))} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[P0]
bestItems의 배열의 길이가 0일때의 처리를 해주면 좋을 것 같습니다.
| @@ -0,0 +1,79 @@ | |||
| import { useEffect, useState } from "react"; | |||
| import { getProducts } from "../../api/index"; | |||
| import { PAGE_SIZE, ORDER } from "../../constants"; | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good!
| useEffect(() => { | ||
| updatePageSize(); | ||
| fetchSortedData({ page, pageSize, order, keyword }); | ||
|
|
||
| window.addEventListener("resize", updatePageSize); | ||
| return () => { | ||
| window.removeEventListener("resize", updatePageSize); | ||
| }; | ||
| }, [page, pageSize, order, keyword]); | ||
|
|
||
| const onPageChange = (pageNum) => { | ||
| setPage(pageNum); | ||
| fetchSortedData({ page: pageNum, pageSize, order, keyword }); | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[P0]
이 부분이 어차피 page가 바뀌면서 useEffect로 인해 fetchSortedData 한번 요청이 될 것 같은데, 그 과정에서 onPageChage 하는 부분에서도 또 fetch를 하고 있어 중복으로 요청이 되지 않는지 확인이 필요합니다!
| @@ -0,0 +1,16 @@ | |||
| export const PAGE_SIZE = { | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[P2]
별도의 파일로 분리 잘하신 것 같습니다. 다만 도메인 단위로 constants/page.constant.js 등과 같이 별도의 파일로 관리해보는 것도 좋을 것 같아요!
backend/server.js
Outdated
|
|
||
| const app = express(); | ||
| app.use(express.json()); | ||
| app.use(cors()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[P0]
이렇게 설정하면 모든 URL에 대해 허용을 해주게 됩니다. 자신이 사용하는 프론트엔드 레포만 허용해줄 수 있도록 설정해주세요!
요구사항
기본
공통프론트엔드 구현 요구사항랜딩 페이지
중고마켓 페이지
상품 등록 페이지
백엔드 구현 요구사항중고마켓
id,name,description,price,tags,createdAt,updatedAt필드를 가집니다.name,description,price,tags를 입력하여 상품을 등록합니다.id,name,description,price,tags,createdAt를 조회합니다.id,name,price,createdAt를 조회합니다.name,description에 포함된 단어로 검색할 수 있습니다..env파일에 환경 변수를 설정해 주세요.심화
프론트엔드 구현 요구사항상품 등록 페이지
주요 변경사항
스크린샷
멘토에게