Skip to content
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

[오정민] Sprint5 #170

Conversation

ojm51
Copy link
Collaborator

@ojm51 ojm51 commented Jun 24, 2024

요구사항

기본

중고마켓

  • 중고마켓 페이지 주소는 “/items” 입니다.
  • 페이지 주소가 “/items” 일때 상단네비게이션바의 '중고마켓' 버튼의 색상은 “3692FF”입니다.
  • 상단 네비게이션 바는 이전 미션에서 구현한 랜딩 페이지와 동일한 스타일로 만들어 주세요.
  • 상품 데이터 정보는 https://panda-market-api.vercel.app/docs/#/ 에 명세된 GET 메소드 “/products” 를 사용해주세요.
  • '상품 등록하기' 버튼을 누르면 “/additem” 로 이동합니다. ( 빈 페이지 )
  • 전체 상품에서 드롭 다운으로 “최신 순” 또는 “좋아요 순”을 선택해서 정렬을 할 수 있습니다.

중고마켓 반응형

  • 베스트 상품
    • Desktop : 4개 보이기
    • Tablet : 2개 보이기
    • Mobile : 1개 보이기
  • 전체 상품
    • Desktop : 12개 보이기
    • Tablet : 6개 보이기
    • Mobile : 4개 보이기

심화

  • 페이지 네이션 기능을 구현합니다.

스크린샷

Pasted Graphic
image

멘토에게

  • 기본 요구사항은 모두 충족하도록 구현하였습니다.
  • 반응형과 페이지네이션은..차차 해보도록 하겠습니다🥲

@ojm51 ojm51 requested a review from Taero-Kim June 24, 2024 15:00
@@ -0,0 +1,15 @@
import "./Menu.css";

function Menu({ href, className, name, onClick }) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

p5;
NavItem과 같은 컴포넌트 명도 괜찮을 것 같아요!

if (!response || !response.ok) return [];
const result = await response.json();

const data = result.list.map((products) => ({
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

p4;
요건 map을 사용하지 않고 데이터에 result.list를 바로 할당했을 때, 어떤 불필요한 데이터들이 많나요?
그게 아니라면 map할 필요 없이
result.list를 바로 리턴해도 괜찮을 것 같아요!

const fetchProductData = async () => {
  ...

  const result = await response.json();
  return result.list;
}


useEffect(() => {
console.log("products: ", products);
console.log("order: ", order);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

p5;
console.log({ products, order });
소소한 팁인데 요렇게 객체 형식으로 콘솔을 찍어도 편하게 확인할 수 있습니다!

console.log("products: ", products);
console.log("order: ", order);

const sortedProducts = [...products].sort((a, b) => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

배열의 sort 자체가 mutable하여 원본을 변경시킨다는 걸 잘 알고 계신 것 같네요!
스프레드 연산자로 원래 products의 복사본을 잘 사용하셨어요!

return b[order] - a[order];
});
setShowedProducts(sortedProducts.slice(0, 10));
}, [order, products]);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

p4;
사실 useEffect는 사용 전에, 정말 useEffect가 필요한지에 대해 다시 한 번 생각해보는게 좋아요!

요렇게 내가 관리하고 있는 어떤 state들 <(ex) order, products)..>
이런 state들을 통해 계산되고 파생되는 state라면 <(ex) showedProducts ..>
useEffect 보다는 useMemo 등의 훅을 활용할 수 있어요!

useEffect는 사실 렌더링과는 관련없는 이펙트를 다루는 훅이어서,
최대한 그 용도로만 사용하는게 좋습니다!

이와 관련해서는 멘토링 세션때 다시 언급드리도록 하겠습니다.
이와 별개로, 그래도 잘 하셨습니다!

id="order"
onChange={handleOrderChange}
>
<option value="createdAt">최신순</option>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

p4;
<AllProductList /> 컴포넌트에서도 상태로 사용되고,
상품의 sorting 기준은 잘 변하지 않으며, 다른 곳에서도 사용될 여지가 있는 항목들이기 때문에
createdAt과 favoriteCount는 상수로 관리해도 괜찮을 것 같아요!

ex)

별도의 js파일에 관리하는걸 추천드려요!
export const PRODUCT_SORT_OPTIONS = Object.freeze({
  CREATED_AT: createdAt,
  FAVORITE_COUNT: favoriteCount
})

<AllProductList />
const [order, setOrder] = useState(PRODUCT_SORT_OPTIONS.CREATED_AT);

<AllProductListItem />
<option value={PRODUCT_SORT_OPTIONS.CREATED_AT}>최신순</option>
<option value={PRODUCT_SORT_OPTIONS.FAVORITE_COUNT>좋아요순</option>

import ProductListItem from "./ProductListItem";

function BestProductList({ products }) {
const sortedProducts = products.sort(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

p4;
요렇게 최신상품과 인기상품을 필요할때마다 전체상품(products) 기반으로 sort하고 계시네요!
요런 부분을 한 번 유틸함수로 분리하여 사용해보는건 어떨까요?

아래처럼 가져다가 사용 가능하도록요! (시간이 되면 한 번 연습해보세요!)

const bestProducts = getSortedProducts({ sortOption: 'favoriteCount', sliceCount: 4}); // 인기 상품
const latestProducts = getSortedProducts({ sortOption: 'createdAt', sliceCount: 10}); // 최신 상품

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+) sort는 원본을 변경시키므로 products를 그대로 가져다 사용하면 안될 것 같아요!

@Taero-Kim
Copy link
Collaborator

정민님 전반적으로 코드를 깔끔하게 잘 작성하신 것 같아요!
전체적인 코드를 보면 리액트의 기본 컨셉을 잘 이해하고 계신다는 생각이 들어요!
지금 처럼 계속 코드 작성하면서 앞으로 리액트와 더 친해지도록 해봐요.

아직 어떤 훅을 어떤 상황에 사용해야하는지 조금 헷갈릴 수 있는데,
그건 앞으로 리액트 학습하시면서 다양한 훅을 배우고 적용하다 보면 익숙해 질거에요!

@ojm51 ojm51 changed the base branch from main to React-오정민 June 26, 2024 00:10
@Taero-Kim Taero-Kim merged commit f3a8779 into codeit-bootcamp-frontend:React-오정민 Jun 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants