Skip to content

Conversation

@cksrlcks
Copy link
Collaborator

@cksrlcks cksrlcks commented Jan 16, 2025

요구사항

기본

상품 등록 페이지

  • 상품 등록 페이지 주소는 "/addboard" 입니다.
  • 게시판 이미지는 최대 한개 업로드가 가능합니다.
  • 각 input의 placeholder 값을 정확히 입력해주세요.
  • 이미지를 제외하고 input 에 모든 값을 입력하면 '등록' 버튼이 활성화 됩니다.
    상품 상세 페이지
  • 상품 상세 페이지 주소는 "/board/{id}" 입니다.
  • 댓글 input 값을 입력하면 '등록' 버튼이 활성화 됩니다.
  • 활성화된 '등록' 버튼을 누르면 댓글이 등록됩니다

심화

  • 회원가입, 로그인 api를 사용하여 받은accessToken을 사용하여 게시물 등록을 합니다.
  • '등록' 버튼을 누르면 게시물 상세 페이지로 이동합니다.

주요 변경사항

  • 미션9에서 리뷰해주신 내용 적용했습니다.
    • axios get요청에 params config 사용
    • PropsWithChildren 사용
    • util 함수 인풋에대한 검증 추가
    • 이미지 업로드 개선 (전달받은 File을 그대로 전달해서 사용)
  • 멘토링시간에 말해주셔서 react query 적용해보았습니다. (코멘트 부분)
    • ssr로 처음 초기데이터를 사용하면서 infinitequeries를 이용해서 더불러오기로 작성했습니다.

스크린샷

image image

멘토에게

- 배열이 아닌 값도 처리할 수 있도록 개선
- 중고마켓 : 배열, 자유게시판 : 일반값
- 중고마켓, 자유게시판 두곳에서 사용할 수 있도록 개선
- axios는 400이상에 error를 throw를 해버려서 바로 error페이지로 이동하게 됨 (try,catch필요)
- try문안에서는 에러를 발생되면 catch로 잡아서 에러 핸들링하도록 변경
- catch문안에서 redirect, notfound를 쓰고 (예상된 에러), 나머지에러는 error페이지로 이동 (예상하지 못한 에러)
- id가 정확이 없으면 리스트로 이동
@cksrlcks cksrlcks requested a review from Lanace January 16, 2025 06:11
Comment on lines +40 to +55
export const COMMENT_PLACEHOLDER: { [key: string]: string } = {
articles: "댓글을 입력해주세요.",
products:
"개인정보를 공유 및 요청하거나, 명예 훼손, 무단 광고, 불법 정보 유포시 모니터링 후 삭제될 수 있으며, 이에 대한 민형사상 책임은 게시자에게 있습니다.",
};

export const COMMENT_TITLE: { [key: string]: string } = {
articles: "댓글달기",
products: "문의하기",
};

export const COMMENT_SUBJECT: { [key: string]: string } = {
articles: "댓글",
products: "문의",
};

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

코멘트 컴포넌트를 혹시나 재사용하는 경우에 여기에 필요한 placholder나 문구를 셋팅해두고 하나의 컴포넌트로 쓰도록 해보았습니다.

  • 처음에는 코멘트컴포넌트안에서 aritcles이냐 products냐 구분해서 문구들을 분기하려고 했는데, 만약에 다른 페이지가 추가되면 또 분기를 나눠야할것같아서 객체를 만들어두고 키로 접근해서 사용하도록 해봤습니다.

Copy link
Collaborator

Choose a reason for hiding this comment

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

와 너무 잘 하신것같아요ㅋㅋㅋ
이러면 관리하기도 좋고 나중에 추가되었을때 어디를 보아야하는지도 명확해지겠죠?

조금더 typescript를 이용해보면 새로운 타입이 추가되었을때 빌드타임에 에러나게 할 수 있어요.
아래코드를 참고해보면 좋을것같아요!

type ItemType = "articles" | "products";

export const COMMENT_PLACEHOLDER: Record<ItemType, string> = {
  articles: "댓글을 입력해주세요.",
  products:
    "개인정보를 공유 및 요청하거나, 명예 훼손, 무단 광고, 불법 정보 유포시 모니터링 후 삭제될 수 있으며, 이에 대한 민형사상 책임은 게시자에게 있습니다.",
};

export const COMMENT_TITLE: Record<ItemType, string> = {
  articles: "댓글달기",
  products: "문의하기",
};

export const COMMENT_SUBJECT: Record<ItemType, string> = {
  articles: "댓글",
  products: "문의",
};

이러면 나중에 ItemType에 뭐가 추가되면 연결된 다른곳들 다 에러가 날꺼에요
typescript의 에러를 사용해서 어디를 수정해야할지 빠르게 확인할 수 있겠죠ㅎㅎ

@cksrlcks cksrlcks added the 순한맛🐑 마음이 많이 여립니다.. label Jan 16, 2025
Copy link
Collaborator

@Lanace Lanace 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 +14 to +16
const [formStatus, formAction, isPending] = useActionState(action, {
message: "",
});
Copy link
Collaborator

Choose a reason for hiding this comment

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

저도 실무에서 써본적이 없긴 한데, 보니까 써볼만 한것같긴 하네여...!ㅎㅎ
👍

interface ArticleFormProps {
initialData?: Article;
mode?: "add" | "edit";
articleId?: number;
Copy link
Collaborator

Choose a reason for hiding this comment

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

articleId 값은 initialData 에 포함되어있지 않을까요...?

Copy link
Collaborator

Choose a reason for hiding this comment

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

요거는 타입 추론을 이용하면 좋을것같아요.

mode가 add 이면 딱히 initialData나 articleId가 필요없지 않나요...?

type ArticleFormProps = ArticleEditFormProps | ArticleAddFormProps;

type ArticleEditFormProps = {
  initialData?: any;
  mode: "edit";
  articleId?: number;
};

type ArticleAddFormProps = {
  mode: "add";
};

이런식으로 합성해서 사용할 수 있어요.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

오 이거 엄청 고민하던건데 감사합니다.;;;

Comment on lines +32 to +34
const { handleArticleAdd, handleArticleModify } =
useArticleActions(articleId);
const onFormSubmit = mode === "add" ? handleArticleAdd : handleArticleModify;
Copy link
Collaborator

Choose a reason for hiding this comment

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

이건 좀 취향을 탈수도 있는데... 저는 컴포넌트에서 API 통신하는걸 그다지 선호하진 않거든요...

왜냐하면 이 ArticleForm은 단순 Form인데, 결과적으로 이게 submit 되었을떄 add할지 edit할지는 이 컴포넌트를 가져다가 사용하는 사람이 결정하는게 좋다고 생각해서요ㅎㅎ;;

그래서 차라리 ArticleFormProps 에 onSubmit 메소드를 받는게 어떨까 싶어요!

Copy link
Collaborator Author

@cksrlcks cksrlcks Jan 17, 2025

Choose a reason for hiding this comment

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

form컴포넌트를 불러서 사용하는쪽에서 원하는 submit기능을 주입하도록 변경하는거네요. 감사합니다. ^^

image,
title,
content,
writer: { nickname, id: ownerId },
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 +3 to +5
export default function Loading() {
return <Message>코멘트를 가져오는중입니다...</Message>;
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

오 loading.tsx 도 쓸줄아시는군요...! 👍

Comment on lines +1 to +2
export default function ArticleDetailPage() {
return <></>;
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 +20
useInfiniteQuery({
queryKey: ["comments", name, id],
queryFn: ({ pageParam = undefined }) =>
getComments(name, { id, cursor: pageParam }),
getNextPageParam: (lastPage) => lastPage.nextCursor,
initialPageParam: 0,
initialData: {
pageParams: [0],
pages: [initialComments],
},
Copy link
Collaborator

Choose a reason for hiding this comment

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

이건 문서보고 해보신건가요??
useQuery만 알려드렸던건데 이거까지 쓰실줄은 몰랐는데...ㅋㅋ;;

잘 쓰셨네여ㅎㅎ

@Lanace Lanace merged commit e50ea86 into codeit-bootcamp-frontend:Next-김찬기 Jan 17, 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