Skip to content

Conversation

@heewls
Copy link
Collaborator

@heewls heewls commented Mar 10, 2025

요구사항

기본

  • 자유 게시판 페이지 주소는 “/boards” 입니다.
  • 전체 게시글에서 드롭 다운으로 “최신 순” 또는 “좋아요 순”을 선택해서 정렬을 할 수 있습니다.
  • 게시글 목록 조회 api를 사용하여 베스트 게시글, 게시글을 구현합니다.
  • 게시글 title에 검색어가 일부 포함되면 검색이 됩니다.
  • 반응형 디자인을 구현해주세요.

심화

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

주요 변경사항

스크린샷

멘토에게

  • app router로 진행했습니다!
  • 추후 loading 파일도 진행할 예정입니다

@heewls heewls self-assigned this Mar 10, 2025
@heewls heewls added the 매운맛🔥 뒤는 없습니다. 그냥 필터 없이 말해주세요. 책임은 제가 집니다. label Mar 10, 2025
@heewls heewls requested a review from kiJu2 March 10, 2025 17:30
@kiJu2
Copy link
Collaborator

kiJu2 commented Mar 11, 2025

스프리트 미션 하시느라 수고 많으셨어요.
학습에 도움 되실 수 있게 꼼꼼히 리뷰 하도록 해보겠습니다. 😊

@kiJu2
Copy link
Collaborator

kiJu2 commented Mar 11, 2025

app router로 진행했습니다! 추후 loading 파일도 진행할 예정입니다

오호 ~ App Router 좋지요 😊😊

Comment on lines +13 to +20
const { initialAllData, initialBestData } = await getBoardsData();

return (
<div className="flex justify-center items-center my-10 lg:my-0">
<div className="max-w-[1200px] min-w-[343px] px-6 lg:p-4 md:p-6 flex flex-col gap-10">
<Best initialData={initialBestData} />
<All initialData={initialAllData} />
</div>
Copy link
Collaborator

Choose a reason for hiding this comment

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

오호.. 초기 데이터를 받아와서 TTV를 빠르게 하셨군요 ..? 🫢🫢

훌륭합니다. ㄷㄷㄷ 첫 코드부터 기대되는데요 ?

TTV: 사용자가 웹브라우저에서 내용을 볼 수 있는 시점

export const revalidate = 60;

export default async function Boards() {
const { initialAllData, initialBestData } = await getBoardsData();
Copy link
Collaborator

Choose a reason for hiding this comment

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

각기 다른 예외 처리를 하기에 어려울 것 같아요.

서로 다른 쿼리로 통신 하고 있기에 다른 에러가 발생할 여지가 있으나(물론 해당 코드에는 예외처리가 없긴 하지만), 이렇게 처리하면 특정 API의 예외처리를 하기 어려울 것 같군요 !

Copy link
Collaborator

Choose a reason for hiding this comment

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

또한, 현재 직렬처리로 되어있는데 병렬로 처리하시면 성능에 도움이 됩니다 !

Suggested change
const { initialAllData, initialBestData } = await getBoardsData();
const allData = await getBoards({
page: 1,
pageSize: 10,
orderBy: "recent",
keyword: "",
});
const bestData = await getBoards({
page: 1,
pageSize: 3,
orderBy: "like",
keyword: "",
});
// ..........
const [ allData, bestData ] = await Promise.all([
getBoards({
page: 1,
pageSize: 10,
orderBy: "recent",
keyword: "",
}),
getBoards({
page: 1,
pageSize: 3,
orderBy: "like",
keyword: "",
})
])

Copy link
Collaborator

Choose a reason for hiding this comment

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

크으 ~ not found까지 꼼꼼하네요 👍👍👍

const [bestItems, setBestItems] = useState<BoardItem[]>(initialData);
const { showItems } = useResize(1, 2, 3);

const best = bestItems.slice(0, showItems);
Copy link
Collaborator

Choose a reason for hiding this comment

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

(선택) useMemo를 사용해볼 수 있을 것 같아요:

Suggested change
const best = bestItems.slice(0, showItems);
const best = useMemo(() => bestItems.slice(0, showItems), [bestItems, showItems]);

배열을 정렬하거나 슬라이스를 하는 것은 아이템 수에 따라 성능 차이가 있을 수 있기에 선택적으로 추천드립니다 ! 😊

Comment on lines +4 to +8
export default function usePagination({
totalBoards,
currentPage,
pageSize,
}: PagingProps) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

크으.. 페이지네이션도 훅으로 빼시다니 👍

Comment on lines +11 to +14
const pageGroup = Math.ceil(currentPage / 5);
const totalPages = Math.ceil(totalBoards / pageSize);
const startPage = (pageGroup - 1) * 5 + 1;
const endPage = Math.min(startPage + 4, totalPages);
Copy link
Collaborator

Choose a reason for hiding this comment

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

마법수가 많이 보이는 군요 !

Suggested change
const pageGroup = Math.ceil(currentPage / 5);
const totalPages = Math.ceil(totalBoards / pageSize);
const startPage = (pageGroup - 1) * 5 + 1;
const endPage = Math.min(startPage + 4, totalPages);
const pageGroup = Math.ceil(currentPage / PAGE_GROUP_SIZE);
const totalPages = Math.ceil(totalBoards / pageSize);
const startPage = (pageGroup - 1) * PAGE_GROUP_SIZE + 1;
const endPage = Math.min(startPage + PAGE_GROUP_SIZE - 1, totalPages);

상수를 통하여 가독성을 향상시켜볼 수 있어요 !

마법 수(Magic Number): 매직 넘버(Magic number)는 코드에서 하드 코딩된(literal value) 일정한 값을 의미하는 숫자나 문자열 등을 의미합니다.

@@ -0,0 +1,30 @@
import { useRouter, useSearchParams } from "next/navigation";

export default function useParams() {
Copy link
Collaborator

Choose a reason for hiding this comment

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

와우 ㄷㄷ.. 페이지네이션의 쿼리를 읽는 훅이군요? 좋은 아이디어로 보이네요:

Suggested change
export default function useParams() {
export default function usePaginamtionQueries() {

조심스레 이름을 제안드려보고 싶어요 ! useParams는 목적이 범용적으로 보일 수 있을 것 같아서요 !

@kiJu2
Copy link
Collaborator

kiJu2 commented Mar 11, 2025

크으.. 너무 멋진데요 ? App router도 정복하셨군요?
서버 컴포넌트에서 초기 데이터를 불러서 클라이언트 컴포넌트의 초기 렌더링에 동적인 데이터를 즉시 출력 하신 점.
커스텀 훅들을 능숙하게 활용하신 점이 인상깊어요.

훌륭합니다. 보면서 감탄했어요 굿굿 ! 👍👍

@kiJu2 kiJu2 merged commit 0436e25 into codeit-bootcamp-frontend:Next-김희진 Mar 11, 2025
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