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

[김희성] Sprint 8 #114

Conversation

HEES56
Copy link
Collaborator

@HEES56 HEES56 commented Feb 27, 2025

요구사항

기본

  • [o] Github에 스프린트 미션 PR을 만들어 주세요.
  • [o] Next.js를 사용해 진행합니다.

자유 게시판 페이지

  • [o] 게시글 목록에서 드롭다운을 사용하여 "최신 순"으로 정렬할 수 있도록 합니다.
  • [o] 본인이 이전 미션에서 생성한 게시글 목록 조회 API를 활용해 GET 메서드로 데이터를 가져옵니다.
  • [o] 게시글 제목에 검색어가 일부 포함되면 해당 게시글을 검색할 수 있도록 합니다.
  • [o] 이미지는 디폴트 이미지로 프론트엔드에서 처리해 주세요.
  • [o] 게시글 닉네임 및 좋아요 개수 역시 임의값으로 프론트엔드에서 처리해주세요.
  • [o] 베스트 게시글은 최신순 3개 게시글을 요청으로 데이터를 가져와 구현해주세요.
  • [o] 자유게시판 페이지에서 특정 게시글을 클릭하면 해당 게시물의 상세 페이지로 이동합니다.

게시글 등록 & 수정 페이지

  • [o] 각 input 필드에 정확한 placeholder 값을 입력합니다.
  • [o] 모든 input 필드에 값을 입력하면 '등록' 버튼이 활성화됩니다.
  • [o] 본인이 이전 미션에서 생성한 게시글 생성 API를 활용해 POST 메서드로 게시글을 등록합니다.
  • [o] '등록' 버튼을 누르면 해당 게시물 상세 페이지로 이동합니다.
  • [o] 게시글 수정 페이지 UI는 게시글 등록 페이지와 동일합니다.
  • [o] 본인이 이전 미션에서 생성한 게시글 상세 API의 PATCH 메소드를 사용하여 게시물을 수정합니다.

게시글 상세 페이지

  • [o] 본인이 이전 미션에서 생성한 게시글 상세 API의 GET 메소드를 사용하여 데이터를 가져옵니다.
  • [o] 본인이 이전 미션에서 생성한 게시글 상세 API의 DELETE 메소드를 사용하여 게시물을 삭제합니다.
  • [o] 댓글 input에 값을 입력하면 '등록' 버튼이 활성화됩니다.
  • [o] 본인이 이전 미션에서 생성한 댓글 생성 API를 활용해 POST 메소드로 댓글을 등록합니다.
  • [o] 본인이 이전 미션에서 생성한 댓글 생성 API를 활용해 PATCH 메소드로 댓글을 수정합니다.
  • [o] 본인이 이전 미션에서 생성한 댓글 생성 API를 활용해 DELETE 메소드로 댓글을 삭제합니다.

심화

  • [o] 디자인 시안에 따라 반응형 디자인을 구현합니다.
  • (생략 가능) 원한다면 지금까지 진행한 모든 React 코드를 Next.js로 마이그레이션 해주세요

주요 변경사항

  • js, page router 기반 next.js 사용

스크린샷

localhost_3000_article

localhost_3000_article (1)

localhost_3000_article_modify_a8e6f5a9-c6fd-4f11-84b5-e01edbdd930b

localhost_3000_article_modify

멘토에게

  • 최대한 클린하게 짜볼려고 노력했습니다.. ㅎ
  • 이번엔 컴포넌트를 최대한 분해 해볼려고 했습니다... ㅎ
  • 셀프 코드 리뷰를 통해 질문 이어가겠습니다.

@HEES56 HEES56 requested a review from rjc1704 February 27, 2025 01:49
@HEES56 HEES56 changed the title [sprint] missoin 8 [김희성] missoin 8 Feb 27, 2025
@HEES56 HEES56 changed the title [김희성] missoin 8 [김희성] Sprint 8 Feb 27, 2025
@@ -0,0 +1,71 @@
export async function GET(req) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Page Router 를 사용할 때는 api route 의 함수명은 handler 로 사용하는 것이 맞습니다. App Router 의 route handler 문법로 작성하셔서 이는 프레임워크의 규칙에는 맞지 않아보입니다. Page Router 를 선택하셨다면 Page Router 만의 문법을 따라주시는 것이 좋겠습니다.
https://nextjs.org/docs/pages/building-your-application/routing/api-routes

@@ -0,0 +1,73 @@
import { useState } from "react";

export default function SetComment({ articles, CommentAdd }) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

SetComment 는 동사형 명칭으로 컴포넌트명으로는 적합하지 않습니다. 댓글 등록폼을 의미하는 컴포넌트이니 명사형으로 CommentForm 정도가 적당할 것 같습니다.

@@ -0,0 +1,44 @@
import { useState } from "react";
import Image from "next/image";
import kebabIcon from "../../../public/Img/dropdown-icon/ic_kebab.png";
Copy link
Collaborator

Choose a reason for hiding this comment

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

public 폴더에 접근할 때 상대경로를 여러번 사용하는 것보다는 아래와 같이 절대경로 지정하셔서 사용하는 것을 권장 드립니다.

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"],
      "@public/*": ["public/*"],
      "@images/*": ["public/Img/*"]
    }
  }
}

import ArticleCard from "@/components/article/ArticleCard";
import { useState, useEffect } from "react";

export default function BestArticle({ articles }) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

BestArticle 보다는 BestArticles 또는 BestArticleList 로 복수형 UI 를 암시하는 명칭이 클린코드에 더 가까울 것으로 보입니다.

import sortIcon from "../../../public/Img/dropdown-icon/ic_sort.png";
import dropArrow from "../../../public/Img/dropdown-icon/ic_arrow_down.png";

export function Dropdown() {
Copy link
Collaborator

Choose a reason for hiding this comment

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

컴포넌트명은 모듈파일명칭과 동일하게 해주는 것과 default export 사용하시는 것이 컨벤션입니다.
export default function ArticleCustomSelect() { ... }

@rjc1704
Copy link
Collaborator

rjc1704 commented Mar 3, 2025

희성님 요구사항들에 따라 열심히 작업해주신 것으로 보입니다! 다만 App Router 와 Page Router 는 서로 다른 규칙과 api 를 사용하는 점을 잘 인지하고 공식문서 확인하셔야만 제대로 동작하는 웹사이트를 구성할 수 있다는 점을 꼭 명심하시면 좋겠습니다.
코멘트 확인해보시고 수정해서 동작여부까지 꼭 테스트해보시면 좋겠습니다.

아래 추가적으로 코멘트들 남겨 드리겠습니다.

  • src/hooks/ 폴더에는 커스텀훅들(use 로 시작하는 것들)만 보관하는 것이 리액트 컨벤션입니다. day.js 는 커스텀훅이 아니라 날짜 형식을 지정해주는 유틸리티함수들의 모음이므로 src/utils/ 나 src/lib/ 폴더로 보관하는 것이 좋겠습니다.
  • �useRouter 를 사용하실 때 page router 에서는 "next/navigation"이 아니라 "next/router" 를 사용하시는 것이 맞습니다.
  • article 페이지의 경우, 현재 getServerSideProps 사용하셔서 api 응답을 받기전까지 사용자에게 아무런 UI를 보여주지 않게 됩니다. SEO 가 중요한 페이지라면 getServerSideProps 가 적절한 렌더링 방식이지만, 리스트 페이지는 계속 동적으로 변할 수 있는 부분이기 때문에 보통 리스트 페이지는 SEO보다는 사용자에게 조금이라도 더 빠르게 UI를 보여주는 것이 더 적합한 렌더링 방식입니다. 즉, article 페이지(리스트페이지)의 경우 getServerSideProps(SSR) 보다는 useEffect 로 CSR 방식으로 렌더링하시는 것이 더 적절해 보입니다. 반면 article 상세페이지는 SEO가 중요하게 적용될 수 있는 부분이라 getServerSideProps 적절하게 잘 사용하셨습니다.
  • Image 컴포넌트 사용할 때, width, height 속성은 항상 함께 지정해주는 습관을 들이는 것이 좋겠습니다. 피그마 디자인에서 렌더링 사이즈 확인하고 기입해주시면 layout shift 방지와 이미지 성능최적화에 도움을 줍니다.

@rjc1704 rjc1704 merged commit d5bd870 into codeit-sprint-fullstack:next-김희성 Mar 3, 2025
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants