Skip to content

[7팀 이정운] Chapter 2-3. 관심사 분리와 폴더구조#67

Open
ljwoon1211 wants to merge 23 commits intohanghae-plus:mainfrom
ljwoon1211:main
Open

[7팀 이정운] Chapter 2-3. 관심사 분리와 폴더구조#67
ljwoon1211 wants to merge 23 commits intohanghae-plus:mainfrom
ljwoon1211:main

Conversation

@ljwoon1211
Copy link

@ljwoon1211 ljwoon1211 commented May 1, 2025

과제 체크포인트

https://ljwoon1211.github.io/front_5th_chapter2-3

기본과제

목표 : 전역상태관리를 이용한 적절한 분리와 계층에 대한 이해를 통한 FSD 폴더 구조 적용하기

  • 전역상태관리를 사용해서 상태를 분리하고 관리하는 방법에 대한 이해
  • Context API, Jotai, Zustand 등 상태관리 라이브러리 사용하기
  • FSD(Feature-Sliced Design)에 대한 이해
  • FSD를 통한 관심사의 분리에 대한 이해
  • 단일책임과 역할이란 무엇인가?
  • 관심사를 하나만 가지고 있는가?
  • 어디에 무엇을 넣어야 하는가?

체크포인트

  • 전역상태관리를 사용해서 상태를 분리하고 관리했나요?
  • Props Drilling을 최소화했나요?
  • shared 공통 컴포넌트를 분리했나요?
  • shared 공통 로직을 분리했나요?
  • entities를 중심으로 type을 정의하고 model을 분리했나요?
  • entities를 중심으로 ui를 분리했나요?
  • entities를 중심으로 api를 분리했나요?
  • feature를 중심으로 사용자행동(이벤트 처리)를 분리했나요?
  • feature를 중심으로 ui를 분리했나요?
  • feature를 중심으로 api를 분리했나요?
  • widget을 중심으로 데이터를 재사용가능한 형태로 분리했나요?

심화과제

목표: 서버상태관리 도구인 TanstackQuery를 이용하여 비동기코드를 선언적인 함수형 프로그래밍으로 작성하기

  • TanstackQuery의 사용법에 대한 이해
  • TanstackQuery를 이용한 비동기 코드 작성에 대한 이해
  • 비동기 코드를 선언적인 함수형 프로그래밍으로 작성하는 방법에 대한 이해

체크포인트

  • 모든 API 호출이 TanStack Query의 useQuery와 useMutation으로 대체되었는가?
  • 쿼리 키가 적절히 설정되었는가?
  • fetch와 useState가 아닌 선언적인 함수형 프로그래밍이 적절히 적용되었는가?
  • 캐싱과 리프레시 전략이 올바르게 구현되었는가?

과제 셀프회고

과제에서 좋았던 부분

과제를 하면서 새롭게 알게된 점

과제를 진행하면서 아직 애매하게 잘 모르겠다 하는 점, 혹은 뭔가 잘 안되서 아쉬운 것들

리뷰 받고 싶은 내용이나 궁금한 것에 대한 질문

Comment on lines +8 to +10
const isProd = import.meta.env.MODE === "production"
const basename = isProd ? "/front_5th_chapter2-3/" : ""

Copy link

@jinsoul75 jinsoul75 May 9, 2025

Choose a reason for hiding this comment

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

vite config에 설정하면 좋을것 같아요!

userId: 1,
};

export const useCommentFormStore = create<CommentFormState>((set) => ({

Choose a reason for hiding this comment

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

정운님은 features에 create,edit 를 두셨군요!! delete는 features에 안두신 이유가 있나요?!

Copy link

@jinsoul75 jinsoul75 left a comment

Choose a reason for hiding this comment

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

저번주도 수고하셨습니다 정운님! TDD도 잘해내봅시다 ㅎㅎㅎ

Copy link

@keyonnaise keyonnaise 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 +15 to +17
const handleLike = () => {
if (onLike) onLike(comment)
}

Choose a reason for hiding this comment

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

혹시 optional chaining (?.)을 사용하여 함수를 조건부로 실행하는 대신 if 문을 사용하신 이유는 코드의 직관성 때문일까요?

Comment on lines +91 to +108
function getEnhancedPostsData(
postsData?: PostsResponse,
usersData?: { users: User[] }
): PostsResponse | undefined {
if (!postsData || !usersData) {
return postsData;
}

const enhancedPosts = postsData.posts.map((post: Post) => ({
...post,
author: usersData.users.find((user) => user.id === post.userId),
}));

return {
...postsData,
posts: enhancedPosts,
};
} No newline at end of file

Choose a reason for hiding this comment

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

확실히 함수를 분리해서 관리하는게 코드를 살펴보고 이해하기가 훨씬 더 편한 것 같습니다!

Choose a reason for hiding this comment

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

정운님께서도 쿼리 캐시를 직접 수정하는 방식으로 mutation을 작성하셨군요! 저는 이 방법을 떠올리지 못하고, msw를 사용해서 유사 서버를 구축하여 진행했었습니다...ㅠ

Comment on lines +18 to +39
export const useCommentModalStore = create<CommentModalState>((set) => ({
isCommentAddDialogOpen: false,
isCommentEditDialogOpen: false,
selectedPost: null,
selectedComment: null,

openCommentAddDialog: (post: Post) => set({
isCommentAddDialogOpen: true,
selectedPost: post
}),
closeCommentAddDialog: () => set({
isCommentAddDialogOpen: false
}),

openCommentEditDialog: (comment: Comment) => set({
isCommentEditDialogOpen: true,
selectedComment: comment
}),
closeCommentEditDialog: () => set({
isCommentEditDialogOpen: false
}),
})); No newline at end of file

Choose a reason for hiding this comment

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

모달 부분을 구현하실 때 참고하실 만한 자료를 하나 소개해 드리고 싶어요! 저는 토스에서 제공하는 (useOverlay)[https://www.slash.page/ko/libraries/react/use-overlay/src/useOverlay.i18n]를 참고해 모달 부분을 구현했답니다! 훅을 참고해서 모달을 구현했었답니다! 정운님께서도 혹시 모달 구현에 관심 있으시다면 한번 살펴보시는 것도 좋은 공부가 될 것 같아요!

Comment on lines +34 to +36
export const Button = forwardRef<HTMLButtonElement, ButtonProps>(({ className = "", variant, size, ...props }, ref) => {
return <button className={buttonVariants({ variant, size, className })} ref={ref} {...props} />
})

Choose a reason for hiding this comment

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

React 19 버전으로 업데이트되면서 forwardRef을 명시적으로 사용하지 않아도 되는 것으로 알고 있습니다! 이번 과제에 React 19가 적용되었으니, 이 부분도 한번 고려해보시면 좋을 것 같습니다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants