Skip to content

[김주동] sprint9 #119

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

Conversation

joodongkim
Copy link
Collaborator

요구사항

기본

  • 자유 게시판 페이지 주소는 “/boards” 입니다.
  • 전체 게시글에서 드롭 다운으로 “최신 순” 또는 “좋아요 순”을 선택해서 정렬을 할 수 있습니다.
  • 게시글 목록 조회 api를 사용하여 베스트 게시글, 게시글을 구현합니다.
  • 게시글 title에 검색어가 일부 포함되면 검색이 됩니다.
  • 베스트 상품 기준, 정렬 : like, like가 높은 순
  • 베스트 상품의 기준은, 정렬 : favori, favorite가 가장 높은 상품 4가지를 보여주세요.
  • 베스트 상품 카드 데이터는 제공된 백엔드 API 페이지의 GET 메소드인 “/products”를 사용해주세요.
  • 반응형 디자인을 구현해주세요.

심화

  • [] 반응형으로 보여지는 베스트 게시판 개수를 다르게 설정할때 서버에 보내는 pageSize값을 적절하게 설정합니다.
  • [] next의 data prefetch 기능을 사용해봅니다.

주요 변경사항

  • Component(.tsx)파일 내에 있는 styled-components를 별도의 파일을 분리하였다.

스크린샷

image

멘토에게

  • 셀프 코드 리뷰를 통해 질문 이어가겠습니다.

@joodongkim joodongkim requested a review from GANGYIKIM October 26, 2024 12:06
@joodongkim joodongkim added the 순한맛🐑 마음이 많이 여립니다.. label Oct 26, 2024
@GANGYIKIM GANGYIKIM changed the title Next 김주동 sprint9 [김주동] sprint9 Oct 29, 2024
Copy link
Collaborator

@GANGYIKIM GANGYIKIM left a comment

Choose a reason for hiding this comment

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

주동님 이번 스프린트 미션 고생하셨습니다~
나중에 시간되시면 코드를 기능별로 분리하시는 것을 추천드려요.
지금은 한 파일 안에 로직이 다 들어가 있어 약간 아쉽습니다.
분리하시면 가독성이 많이 좋아질 것 같습니다~

Comment on lines +3 to +8
type IconProps = {
iconComponent: React.FunctionComponent<React.SVGProps<SVGSVGElement>>;
size?: number;
fillColor?: string;
outlineColor?: string;
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

P2:
어떤 경우에는 type을 사용하시고, 어떤 경우에는 interface를 사용하셨는데
타입스크립트에서는 우선적으로 interface 사용을 권장하니 interface를 쓰시고 type의 특징이 필요한 경우 type을 사용하시는 것을 추천드립니다~

const [keyword, setKeyword] = useState("");

useEffect(() => {
const currentKeyword = (router.query.q as string) || "";
Copy link
Collaborator

Choose a reason for hiding this comment

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

P2:
가능하면 as 보다 다른 방식으로 사용해주세요~
q를 string으로 변환하거나 typeof를 통해 타입가드문을 추가해주시면 더 좋을 것 같습니다.


const BestItemsSection: React.FC = () => {
const [itemList, setItemList] = useState<Product[]>([]);
const [pageSize, setPageSize] = useState<number | null>(null);
Copy link
Collaborator

Choose a reason for hiding this comment

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

P2:
pageSize는 number보다는 더 좁은 타입인 1 | 2 | 3이라고 말할 수 있습니다.
이 경우에는 타입을 좁힐 필요가 크게 없지만 일반적으로는 타입은 좁힐 수 있다면 좁히는 것이 좋습니다.

enum PAGE_SIZE_BY_SCREEN {
  PC = 3,
  TABLET = 2,
  MOBILE = 1,
}

const getPageSize = (width: number): PAGE_SIZE_BY_SCREEN => {
  if (width < 768) return PAGE_SIZE_BY_SCREEN.MOBILE;
  if (width < 1200) return PAGE_SIZE_BY_SCREEN.TABLET;

  return PAGE_SIZE_BY_SCREEN.PC;
};

const BestItemsSection = () => {
  const [pageSize, setPageSize] = useState<PAGE_SIZE_BY_SCREEN>();
  ...
}

위의 예시처럼 enum으로 어떤 경우 1,2,3이 되는지를 명시해주셔도 좋습니다.
이렇게 하시면 코드의 의도가 더 명확해집니다.

item: Product;
}

const ItemCard = ({ item }: ItemCardProps) => {
Copy link
Collaborator

Choose a reason for hiding this comment

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

P3:
const ItemCard = ({ name, image, id }: ItemCardProps) => { ... }가 아니라 이렇게 하신 이유가 있을까요?
다른 props를 받는것도 아니라서 item이라는 객체를 받는것보다 name, image, id 이렇게 각각의 값을 전달받는게 사용하기에 더 편할 것 같아서요~

Comment on lines +14 to +16
function getLinkStyle(isActive: boolean) {
return { color: isActive ? "var(--blue)" : undefined };
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

P3:
해당 함수가 실행되면 CSSProperties를 반환하니 아래처럼 반환값을 명시해주시는 것이 더 좋을 것 같습니다.

Suggested change
function getLinkStyle(isActive: boolean) {
return { color: isActive ? "var(--blue)" : undefined };
}
function getLinkStyle(isActive: boolean): CSSProperties['color'] {
return { color: isActive ? "var(--blue)" : undefined };
}

Comment on lines +23 to +48
if (!router.isReady) return;

async function fetchProduct() {
if (!productId) {
setError("상품 아이디가 제공되지 않았어요.");
setIsLoading(false);
return;
}

setIsLoading(true);
try {
const data: Product = await getProductDetail(productId);
if (!data) {
throw new Error("해당 상품의 데이터를 찾을 수 없습니다.");
}
setProduct(data);
} catch (error) {
if (error instanceof Error) {
setError(error.message);
} else {
setError("알 수 없는 오류가 발생했습니다.");
}
} finally {
setIsLoading(false);
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

P3:
useEffect내부에 로직이 너무 길어서 가능하면 custom hook으로 분리하시면 더 가독성에 좋을 것 같아요

const [orderBy, setOrderBy] = useState<ProductSortOption>("recent");
const [page, setPage] = useState(1);
const [pageSize, setPageSize] = useState<number | null>(null);
const [itemList, setItemList] = useState<Product[]>([]);
Copy link
Collaborator

Choose a reason for hiding this comment

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

P3:
타입 명시해주신 것 좋습니다 👍

favoriteCount: number;
}

const LikeButton = ({ productId, isFavorite, favoriteCount }: LikeButtonProps) => {
Copy link
Collaborator

Choose a reason for hiding this comment

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

P2:
productId는 사용하지 않는 값인데 왜 받으신걸까요? 안 쓰는 값은 없는것이 더 좋을 것 같습니다.

Comment on lines +21 to +23
const handleInputChange = (e: ChangeEvent<HTMLTextAreaElement>) => {
setComment(e.target.value);
};
Copy link
Collaborator

Choose a reason for hiding this comment

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

P3:
제가 기억하기로는 debounce 함수를 만들어두셨던걸로 기억하는데
이런 경우에도 적용시켜주시면 더 좋을 것 같아요.
그렇지 않으면 사용자가 값을 입력하면 계속 리렌더링이 되니까요~

@GANGYIKIM GANGYIKIM merged commit 2afcec9 into codeit-bootcamp-frontend:Next-김주동 Oct 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
순한맛🐑 마음이 많이 여립니다..
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants