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

[임귀태] Sprint10 #301

Conversation

KorpoQ
Copy link
Collaborator

@KorpoQ KorpoQ commented Aug 16, 2024

요구사항

기본

  • Github에 PR(Pull Request)을 만들어서 미션을 제출합니다.
  • 피그마 디자인에 맞게 페이지를 구현합니다.
  • 기존의 React, Typescript로 구현한 프로젝트와 별도로 진행합니다.
  • Next.js를 사용합니다.

심화

  • 상품 등록 페이지를 구현합니다.

    • 상품 등록 페이지 주소는 /addboard입니다.
    • 게시판 이미지는 최대 한 개 업로드가 가능합니다.
    • 각 input의 placeholder 값을 정확히 입력합니다.
    • 이미지를 제외하고 input에 모든 값을 입력하면 등록 버튼이 활성화됩니다.
    • 회원가입, 로그인 API를 사용하여 받은 accessToken을 사용하여 게시물을 등록합니다.
    • 등록 버튼을 누르면 게시물 상세 페이지로 이동합니다.
  • 상품 상세 페이지를 구현합니다.

    • 상품 상세 페이지 주소는 /board/{id}입니다.
    • 댓글 input 값을 입력하면 등록 버튼이 활성화됩니다.
    • 활성화된 등록 버튼을 누르면 댓글이 등록됩니다.

멘토에게

  • 템플릿 코드부터 구현해보려 했으나 이번에도...

@KorpoQ KorpoQ self-assigned this Aug 16, 2024
@KorpoQ KorpoQ added the 미완성🫠 죄송합니다.. label Aug 16, 2024
Copy link
Collaborator

@arthurkimdev arthurkimdev left a comment

Choose a reason for hiding this comment

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

리뷰는 머지 이후 진행하겠습니다! 🙏

@arthurkimdev arthurkimdev merged commit c67c5b8 into codeit-bootcamp-frontend:Next-임귀태 Aug 21, 2024
Comment on lines +96 to +98
const handleSortSelection = (sortOption: ArticleSortOption) => {
setOrderBy(sortOption);
};
Copy link
Collaborator

Choose a reason for hiding this comment

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

전반적으로 코드 잘 작성하셨는데요, 불필요한 리랜더링 방지하기 위해 아래처럼 useCallback 사용도 고민 해보면 더 좋겠어요.

const handleSortSelection = useCallback((sortOption: ArticleSortOption) => {
    setOrderBy(sortOption);
  }, []);

Comment on lines +113 to +127
useEffect(() => {
const fetchArticles = async () => {
let url = `https://panda-market-api.vercel.app/articles?orderBy=${orderBy}`;
if (keyword.trim()) {
// encodeURIComponent는 공백이나 특수 문자 등 URL에 포함될 수 없는 문자열을 안전하게 전달할 수 있도록 인코딩하는 자바스크립트 함수예요.
url += `&keyword=${encodeURIComponent(keyword)}`;
}
const response = await fetch(url);
const data = await response.json();
setArticles(data.list);
};

fetchArticles();
}, [orderBy, keyword]);

Copy link
Collaborator

Choose a reason for hiding this comment

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

요거 같은 경우는 useArticles 커스텀 훅을 별도로 빼서 사용하는 방법이 재사용성이 올라가고 공통으로 에러 처리등 일관된 처리를 진행할 수 있어서 아래처럼 빼 보면 좋겠습니다.

  const { articles, loading, error } = useArticles(orderBy, keyword);

Comment on lines +53 to +59
<ImageWrapper>
<Image
fill
src={article.image}
alt={`${article.id}번 게시글 이미지`}
style={{ objectFit: "contain" }}
/>
Copy link
Collaborator

Choose a reason for hiding this comment

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

Next.js Image 컴포넌트 사용 시 sizes 속성을 추가하여 더 나은 이미지 최적화를 할 수 있습니다.
아래 문서를 참조해주세요~
https://nextjs.org/docs/pages/api-reference/components/image

Comment on lines +1 to +16
import { useState, useEffect } from "react";

const useViewport = () => {
const [width, setWidth] = useState(0);

useEffect(() => {
const handleWindowResize = () => setWidth(window.innerWidth);
handleWindowResize();
window.addEventListener("resize", handleWindowResize);
return () => window.removeEventListener("resize", handleWindowResize);
}, []);

return width;
};

export default useViewport;
Copy link
Collaborator

Choose a reason for hiding this comment

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

해당 함수 경우 resize 실행 될 때 최적화가 필요합니다. 이럴 땐 연속적인 이벤트가 발생 시 마지막 이벤트만 처리하는 debounce 개념을 통해 해결할 수 있어요.

아래처럼 리팩토링 할 경우, 불필요한 연산을 줄이고 성능을 향상 시킬 수 있습니다. lodash/debounce 라이브러리 크기가 무겁다면, just-debounce 사용해도 무방해요.

Copy link
Collaborator

Choose a reason for hiding this comment

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

import debounce from 'lodash/debounce';

function useViewport() {
  const [width, setWidth] = useState(() => 
    typeof window !== 'undefined' ? window.innerWidth : 0
  );

  const handleWindowResize = useCallback(() => {
    const newWidth = window.innerWidth;
    if (newWidth !== width) {
      setWidth(newWidth);
    }
  }, [width]);

  useEffect(() => {
    if (typeof window === 'undefined') return;

    const debouncedHandleResize = debounce(handleWindowResize, 150);

    window.addEventListener('resize', debouncedHandleResize);
    
    return () => {
      debouncedHandleResize.cancel(); // Lodash debounce의 cancel 메서드
      window.removeEventListener('resize', debouncedHandleResize);
    };
  }, [handleWindowResize]);

  return width;
}

export default useViewport;

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.

2 participants