Skip to content

[9팀 임규원] Chapter 2-3. 관심사 분리와 폴더구조#47

Open
q1Lim wants to merge 29 commits intohanghae-plus:mainfrom
q1Lim:main
Open

[9팀 임규원] Chapter 2-3. 관심사 분리와 폴더구조#47
q1Lim wants to merge 29 commits intohanghae-plus:mainfrom
q1Lim:main

Conversation

@q1Lim
Copy link

@q1Lim q1Lim commented Aug 14, 2025

과제 체크포인트

기본과제

목표 : 전역상태관리를 이용한 적절한 분리와 계층에 대한 이해를 통한 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가 아닌 선언적인 함수형 프로그래밍이 적절히 적용되었는가?
  • 캐싱과 리프레시 전략이 올바르게 구현되었는가?
  • 낙관적인 업데이트가 적용되었는가?
  • 에러 핸들링이 적절히 구현되었는가?
  • 서버 상태와 클라이언트 상태가 명확히 분리되었는가?
  • 코드가 간결하고 유지보수가 용이한 구조로 작성되었는가?
  • TanStack Query의 Devtools가 정상적으로 작동하는가?

최종과제

  • 폴더구조와 나의 멘탈모데일이 일치하나요?
  • 다른 사람이 봐도 이해하기 쉬운 구조인가요?

과제 셀프회고

이번 과제를 통해 이전에 비해 새롭게 알게 된 점이 있다면 적어주세요.

본인이 과제를 하면서 가장 애쓰려고 노력했던 부분은 무엇인가요?

아직은 막연하다거나 더 고민이 필요한 부분을 적어주세요.

이번에 배운 내용 중을 통해 앞으로 개발에 어떻게 적용해보고 싶은지 적어주세요.

챕터 셀프회고

클린코드와 아키테쳑 챕터 함께 하느라 고생 많으셨습니다!
지난 3주간의 여정을 돌이켜 볼 수 있도록 준비해보았습니다.
아래에 적힌 질문들은 추억(?)을 회상할 수 있도록 도와주려고 만든 질문이며, 꼭 질문에 대한 대답이 아니어도 좋으니 내가 느꼈던 인사이트들을 자유롭게 적어주세요.

클린코드: 읽기 좋고 유지보수하기 좋은 코드 만들기

  • 더티코드를 접했을 때 어떤 기분이었나요? ^^; 클린코드의 중요성, 읽기 좋은 코드란 무엇인지, 유지보수하기 쉬운 코드란 무엇인지에 대한 생각을 공유해주세요

결합도 낮추기: 디자인 패턴, 순수함수, 컴포넌트 분리, 전역상태 관리

  • 거대한 단일 컴포넌트를 봤을때의 느낌! 처음엔 막막했던 상태관리, 디자인 패턴이라는 말이 어렵게만 느껴졌던 시절, 순수함수로 분리하면서 "아하!"했던 순간, 컴포넌트가 독립적이 되어가는 과정에서의 깨달음을 들려주세요

응집도 높이기: 서버상태관리, 폴더 구조

  • "이 코드는 대체 어디에 둬야 하지?"라고 고민했던 시간, FSD를 적용해보면서의 느낌, 나만의 구조를 만들어가는 과정, TanStack Query로 서버 상태를 분리하면서 느낀 해방감(?)등을 공유해주세요

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

Copy link

@susmisc14 susmisc14 left a comment

Choose a reason for hiding this comment

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

안녕하세요! AI 코드 리뷰어입니다. 🤖
FSD 적용 + 댓글 도메인 TanStack Query 도입 Pull Request에 대한 리뷰를 완료했어요. 함께 코드를 더 발전시켜 볼까요?

Note

✨ 이번 PR 한 줄 요약
댓글 도메인에 TanStack Query와 Query Key Factory를 도입하고, FSD 레이어로 UI를 분리한 좋은 방향성이 보입니다. 다만, 캐시 업데이트 키 사용 버그, Provider/엔트리 중복, 타입/의존성 관리 불일치 등 Must-Fix 이슈가 있어 안정화가 먼저 필요합니다.


🎯 핵심 리뷰 요약

가장 중요한 개선 포인트부터 빠르게 확인해 보세요.

  • [버그] useUpdateCommentMutation에서 잘못된 쿼리 키 사용으로 캐시 업데이트가 적용되지 않음
  • [구조] index.tsx와 main.tsx에 Provider가 이중 정의됨(엔트리/Provider 충돌 가능성)
  • [타입] Comments vs CommentsResponse 이중 정의와 혼용으로 타입 일관성 깨짐
  • [버전/의존성] pnpm을 dependencies에 추가, zustand는 devDependencies에 추가되었으나 미사용
  • [선언적 서버 상태] Posts/users/tags는 여전히 fetch/로컬 상태로 관리 (과제 심화 목표 미충족)
  • [키 일관성] 태그 항목 key로 tag.url 사용(옵셔널) → slug 사용 권장
  • [FSD 적용] features/entities 분리와 Query Key Factory 도입은 좋음. posts/users 도메인에도 확장 필요
  • [DummyJson 한계 대응] 낙관적 업데이트 일부만 적용(좋아요). create/update/delete에도 전략 통일 필요

🔍 상세 리뷰

각 항목에 대한 구체적인 설명과 코드 예시를 준비했어요.

  1. 댓글 업데이트 캐시 갱신 버그: 쿼리 키 오사용

    • 👍 좋은 점: 댓글 도메인에 Query Key Factory(commentQueryKeys)를 도입했고, setQueryData로 부분 캐시 갱신을 시도한 점은 매우 좋습니다.

    • 💡 개선 제안: useUpdateCommentMutation onSuccess에서 list 키로 commentId를 사용하고 있어 캐시가 갱신되지 않습니다. postId 기반 키를 사용해야 합니다.

    • 🤔 이렇게 제안하는 이유: 결합도/응집도 관점에서 “댓글 리스트”는 postId에 응집됩니다. 쿼리 키는 “데이터의 소유자(postId)”에 결합되어야 하며, commentId는 리스트 키가 아닙니다.

    • 💻 코드 예시 (AS-IS vs TO-BE)
      AS-IS

      onSuccess: (response, { id }) => {
        queryClient.setQueryData<Comments>(commentQueryKeys.list(id), (old) => {
          if (!old) return old;
          return {
            ...old,
            comments: old.comments.map((comment) =>
              comment.id === response.id ? response : comment
            ),
          }
        })
      }
      

      TO-BE

      onSuccess: (response) => {
        if (!response.postId) return
        queryClient.setQueryData<CommentsResponse>(
          commentQueryKeys.list(response.postId),
          (old) => {
            if (!old) return old
            return {
              ...old,
              comments: old.comments.map((c) => (c.id === response.id ? response : c)),
            }
          }
        )
      }
      

      또는, variables에 postId를 포함해 의도를 더 명확히 만들 수 있습니다.

      mutationFn: (payload: { id: number; body: string; postId: number }) =>
        updateComment(payload.id, { body: payload.body }),
      onSuccess: (response, { postId }) => {
        queryClient.setQueryData(commentQueryKeys.list(postId), ...)
      }
      
  2. Provider/엔트리 중복 정의: AppProviders vs QueryProvider

    • 👍 좋은 점: React Query Devtools를 포함한 AppProviders를 추가해 DevX를 높였습니다.
    • 💡 개선 제안: index.tsx와 main.tsx가 동시에 존재하며, 각각 다른 Provider(AppProviders vs QueryProvider)를 사용하고 있습니다. Vite의 엔트리 포인트가 하나로 일치해야 하며, Provider 계층도 단일화해야 합니다.
    • 🤔 이렇게 제안하는 이유: 이중 마운트 및 상태 중복/파편화는 디버깅 난이도를 높이고 예측 불가능한 버그를 유발합니다(결합도 증가).
    • 💻 코드 예시 (AS-IS vs TO-BE)
      AS-IS
      // index.tsx
      <Router>
        <AppProviders client={queryClient}>
          <App />
        </AppProviders>
      </Router>
      
      // main.tsx
      <QueryProvider>
        <App />
      </QueryProvider>
      
      TO-BE
      // main.tsx (단일 엔트리)
      import { AppProviders } from './providers/AppProviders'
      
      createRoot(document.getElementById('root')!).render(
        <StrictMode>
          <Router>
            <AppProviders>
              <App />
            </AppProviders>
          </Router>
        </StrictMode>
      )
      
      • QueryProviders 파일은 제거하고 AppProviders만 유지
      • index.tsx 파일은 제거(또는 main.tsx로 통합)
  3. 타입 일관성: Comments vs CommentsResponse 혼용

    • 👍 좋은 점: 타입을 도메인 중심으로 분리했습니다.
    • 💡 개선 제안: Comments와 CommentsResponse가 동일한 구조로 중복 정의되어 혼용되고 있습니다. 단일 타입으로 통일하고, API 응답 스키마와 도메인 모델이 다르다면 명확히 구분하세요.
    • 🤔 이렇게 제안하는 이유: 타입 중복은 유지보수 비용을 늘리고, setQueryData 제네릭 인수와 반환값 불일치로 인해 런타임 버그를 유발합니다(응집도 저하).
    • 💻 코드 예시 (AS-IS vs TO-BE)
      AS-IS
      // setQueryData<Comments> ... setQueryData<CommentsResponse> 혼용
      
      TO-BE
      export interface CommentsList { // 단일 타입
        comments: Comment[]
        limit: number
        skip: number
        total: number
      }
      // setQueryData<CommentsList>로 일원화
      
  4. 의존성/버전 관리: pnpm, zustand

    • 👍 좋은 점: 최신 스택(React 19, TanStack Query v5)을 사용합니다.
    • 💡 개선 제안:
      • pnpm은 패키지 매니저로, 프로젝트 runtime dependencies에 포함되면 안 됩니다. 제거하세요.
      • zustand는 devDependencies에 추가되어 있으나 사용되지 않습니다. 미사용 패키지는 제거하거나 실제 사용 시 dependencies로 옮기세요.
    • 🤔 이렇게 제안하는 이유: 불필요한 의존성은 번들 크기와 공격 면적을 증가시키며, lockfile/빌드 최적화에도 악영향을 줍니다.
  5. 서버 상태 선언화(심화 목표): posts/users/tags는 여전히 fetch/로컬 상태

    • 👍 좋은 점: 댓글 도메인은 TanStack Query로 잘 추상화했습니다. Query Key Factory를 도입한 점도 훌륭합니다.
    • 💡 개선 제안:
      • posts, users, tags도 각각 entities/post|user|tag에 query/mutation 레이어를 만들고 tanstack-query로 통일하세요.
      • 현재 pages/PostsManagerPage가 너무 많은 서버상태/이벤트를 소유합니다. features 레이어의 model 훅으로 추상화하면 응집도가 올라갑니다.
    • 🤔 이렇게 제안하는 이유: “서버 상태는 선언적으로”라는 심화 과제 목표와 직결됩니다. fetch + useState 패턴은 캐싱/리트라이/에러 경계/동시성 제어가 어렵고 결합도가 높습니다.
    • 💻 코드 예시 (TO-BE)
      // entities/post/model/queryKeys.ts
      export const postQueryKeys = {
        all: ['posts'] as const,
        list: (params: { limit: number; skip: number }) => [...postQueryKeys.all, 'list', params] as const,
        detail: (id: number) => [...postQueryKeys.all, 'detail', id] as const,
      }
      
      // entities/post/model/queries.ts
      export const usePostsQuery = (params) =>
        useQuery({
          queryKey: postQueryKeys.list(params),
          queryFn: () => getPosts(params.limit, params.skip),
          staleTime: 30_000,
          gcTime: 5 * 60_000,
        })
      
  6. 낙관적 업데이트 전략 통일 + DummyJson 한계 대응

    • 👍 좋은 점: 댓글 좋아요에 onMutate 기반 낙관적 업데이트를 적용했습니다.
    • 💡 개선 제안:
      • create/update/delete에도 낙관적 업데이트를 적용하거나, onSettled invalidate로 일관성을 확보하세요.
      • DummyJson은 CUD가 서버에 영속되지 않습니다. 데모 일관성을 위해 아래 대안을 적용하세요.
        • 대안 1: tanstack-query 캐시 직접 수정(현재 방향) + onError 롤백 철저히 관리
        • 대안 2: MSW로 API 모킹하여 CUD를 로컬 DB(state)로 반영
    • 🤔 이렇게 제안하는 이유: 서버-클라이언트 상태 분리가 심화 목표의 핵심입니다. 낙관적 업데이트 일관성은 UX와 데이터 정합성 모두에 중요합니다.
    • 💻 코드 예시 (TO-BE)
      // onMutate → onError 롤백 → onSettled invalidate
      onMutate: async (payload) => { ...; return { key, previous } }
      onError: (_err, _vars, ctx) => { if (ctx?.previous) queryClient.setQueryData(ctx.key, ctx.previous) }
      onSettled: (_d, _e, vars) => queryClient.invalidateQueries({ queryKey: commentQueryKeys.list(vars.postId) })
      
  7. 태그 렌더링: key와 value에 slug 사용

    • 👍 좋은 점: Tag 타입을 분리하고 필터 UI를 컴포넌트로 추출했습니다.
    • 💡 개선 제안: PostsFilter에서 key={tag.url}은 옵셔널 필드에 의존합니다. key와 value 모두 slug에 통일하세요.
    • 🤔 이렇게 제안하는 이유: React key는 안정적인 식별자여야 하며, url 옵셔널 사용은 예기치 않은 re-mount를 유발할 수 있습니다.
    • 💻 코드 예시
      AS-IS
      <SelectItem key={tag.url} value={tag.slug}>
        {tag.slug}
      </SelectItem>
      
      TO-BE
      <SelectItem key={tag.slug} value={tag.slug}>
        {tag.slug}
      </SelectItem>
      
  8. 타입 안전성: useComment(postId) null 전달, 포스트 상세 댓글 로딩 트리거

    • 👍 좋은 점: PostDetail 열릴 때 postId에 연동해 댓글을 불러오는 구조입니다.
    • 💡 개선 제안:
      • useComment의 인수는 number | undefined로 제한하고, 호출부에서 null을 undefined로 정규화하세요.
      • enabled 옵션과 함께, Dialog open 시점에만 쿼리를 enable하는 패턴을 고려해 네트워크 비용을 줄일 수 있습니다.
    • 🤔 이렇게 제안하는 이유: null/undefined 혼용은 타입 안정성을 떨어뜨리고 런타임 분기 오류를 유발합니다.
    • 💻 코드 예시
      // 호출부
      const postId = selectedPost?.id ?? undefined
      const { ... } = useComment(postId)
      
      // query
      useQuery({ ..., enabled: open && !!postId })
      

🗺️ 전체 개선 로드맵 (우선순위 가이드)

  • P1 (Must-Fix) 🚨

    • useUpdateCommentMutation onSuccess 키 오사용 수정(postId 기반)
    • 엔트리/Provider 단일화(main.tsx만 유지, AppProviders로 통합)
    • 타입 정리: Comments vs CommentsResponse 통일
    • package.json에서 pnpm 제거, 미사용 zustand 정리(사용 시 dependencies로 이동)
    • PostsFilter SelectItem key를 slug로 교체
  • P2 (Recommended) ⚠️

    • posts/users/tags API를 tanstack-query로 전환, Query Key Factory 확장
    • 낙관적 업데이트 전략 통일(onMutate/onError/onSettled)
    • fetch 대신 shared/api/axios로 통일
    • PostDetail/CommentForm 등 다이얼로그 open 상태 기반 enabled 제어로 네트워크 최적화
    • AirBnB import 순서/그룹화, 네이밍 컨벤션 정리
  • P3 (Optional) 💡

    • MSW 도입으로 DummyJson CUD 영속화 시뮬레이션
    • React 19 JSX 자동 런타임 사용 시 파일 상단의 import React 제거하여 보일러플레이트 축소
    • posts도메인 usePosts 훅으로 pages의 상태/이벤트 이관(응집도 향상)
    • Query key와 API 응답 타입에 zod 등으로 런타임 검증 도입

아키텍처 유연성 평가 및 AS-IS → TO-BE 제안

변경 요구사항 시뮬레이션

  • 시나리오 A: 새로운 디자인 시스템 도입
    • AS-IS: shared/ui를 통일해서 사용하는 방향은 좋음. 컴포넌트 추상화 수준이 적절해 교체 용이.
    • TO-BE: 디자인 토큰/테마를 shared/theme로 분리하고, ui 컴포넌트는 토큰만 의존하도록 축소.
  • 시나리오 B: 새로운 핵심 기능 추가(예: 게시물 반응/북마크)
    • AS-IS: pages/PostsManagerPage가 많은 상태와 이벤트를 소유. 기능 추가 시 pages가 비대해질 가능성.
    • TO-BE: features/post/model/usePosts 훅으로 서버 상태와 이벤트를 이동. pages는 orchestration만 담당.
  • 시나리오 C: 테스트 코드 작성
    • AS-IS: 데이터 패칭 로직이 pages에 산재하면 훅 단위 테스트가 어려움.
    • TO-BE: entities/*/model의 queries/mutations를 순수 훅으로 분리하면 Vitest/RTL로 손쉬운 유닛 테스트 가능.

폴더 구조 제안(변형된 FSD, 알파벳 정렬)

src/
  app/                      # 엔트리/루트 레이아웃
  entities/
    comment/
      api/
      model/
        queryKeys.ts
        queries.ts
        mutations.ts
        types.ts
      ui/                   # 아주 얇은 컴포넌트만
    post/
      api/
      model/
      ui/
    user/
      ...
  features/
    comment/
      model/useComment.ts   # 페이지 독립적인 도메인 훅
      ui/CommentForm.tsx
    post/
      model/usePosts.ts     # NEW: posts 관리 훅
      ui/...
  pages/
    posts-manager/          # page-specific 조립만
      index.tsx
  shared/
    api/axios.ts
    lib/queryClient.ts
    theme/
    ui/                     # DS 추상화
  widgets/
    Header.tsx
    Footer.tsx

데이터 흐름(설계 의도 강조)

flowchart LR
  Page[PostsManagerPage] -->|uses| FeaturePost[features/post/model/usePosts]
  Page -->|uses| FeatureComment[features/comment/model/useComment]
  FeaturePost -->|queries/mutations| EntityPost[entities/post/model]
  FeatureComment -->|queries/mutations| EntityComment[entities/comment/model]
  EntityPost --> Axios[shared/api/axios]
  EntityComment --> Axios
Loading

핵심 개념 적용

  • 응집도(Cohesion): 도메인별(entities) 데이터 계약/키/타입을 한 곳에 모아 높은 응집도를 달성합니다.
  • 결합도(Coupling): pages는 features의 퍼사드 훅만 의존해 결합도를 낮춥니다. api/axios, query key 구현 세부는 pages에서 숨겨집니다.
  • 추상화(Abstraction): Query Key Factory로 키 생성을 중앙화하면, 쿼리 무효화/캐시 직접 수정의 추상화 수준이 상승합니다.

코드 일관성 검토

  • 네이밍/폴더
    • features/comment/model/useComment, entities/comment/model/* 일관성 좋습니다.
    • posts/users/tags에도 동일한 queryKeys/queries/mutations 패턴을 확장하세요.
  • import/export
    • 외부 → 절대경로(혹은 alias) → 상대경로 순으로 그룹화 권장(Airbnb 가이드).
    • index re-export(features/index.ts)는 잘 하고 있습니다. entities에도 index.ts 배치해 import 경로를 얕게 유지하세요.
  • 컴포넌트/함수 네이밍
    • 이벤트 핸들러 onXxx, 명령형 함수는 동사 우선(updatePost, deletePost) 일관성 좋음.
  • Toss Frontend Fundamentals
    • “결합도 낮추기”: pages에서 서버 상태를 features로 이동하면 더 준수하게 됩니다.
    • “읽기 좋은 코드”: PostForm/CommentForm로 폼 UI를 공통화한 점 좋습니다.
  • Airbnb JavaScript 스타일
    • Optional chaining과 nullish 병용 시 타입 명확화 권장.
    • React 17+ JSX 자동 런타임 사용 시 import React 생략 가능(프로젝트 tsconfig 확인 후 일괄 정리).

라이브러리 버전 확인

  • React 19.1.1: JSX 자동 런타임가 기본입니다. import React는 필요 없습니다. forwardRef는 여전히 유효합니다.
  • @tanstack/react-query v5.85.3: 현재 사용 방식 적합합니다. cancelQueries/setQueryData/optimistic update API 정상.
  • @tanstack/react-query-devtools v5: AppProviders에서 올바르게 사용.
  • zustand v5: 현재 코드에서 미사용. 사용 의도 없다면 제거 권장.
  • pnpm: 의존성에 추가할 대상이 아님. 제거 권장.

과제 특수성 반영: DummyJson 한계와 대안

  • 현재 좋아요에 낙관적 업데이트(onMutate) 적용은 적절합니다. 동일 전략을 create/update/delete에도 확장하세요.
  • 대안 1: tanstack-query 캐시 직접 수정
    • 장점: 즉시 반응, 서버 비영속 문제를 UX로 가림
    • 주의: onError 롤백, onSettled invalidate 설계 필수
  • 대안 2: MSW 도입
    • 장점: API를 로컬에서 진짜처럼 영속화/변형 가능, 테스트 용이
    • 제안: src/mocks/handlers.ts에 posts/comments/users 핸들러 정의 → worker.start()로 개발 모드에만 활성화

기술적 인사이트

  • 변형된 FSD 아키텍처의 장점
    • 알파벳 정렬/레이어 구분은 멘탈 모델 구축과 탐색 용이성 향상에 도움.
    • entities는 데이터 계약의 단일 출처(SSOT), features는 사용자 행동의 단일 출처가 됩니다.
  • Query Key Factory의 효과
    • 쿼리 키 중앙화로 invalidateQueries/setQueryData 사용성을 높이고, 타입 안정성이 보장됩니다.
    • 키 변경 시 전역 refactor 범위 최소화.
  • posts/users에도 Key Factory 확장
    export const userQueryKeys = {
      all: ['users'] as const,
      list: (params?: { limit?: number }) => [...userQueryKeys.all, 'list', params ?? {}] as const,
      detail: (id: number) => [...userQueryKeys.all, 'detail', id] as const,
    }
    

🤔 한 걸음 더: 코드와 의도 돌아보기

PR 본문을 통해 개발자님의 깊은 고민을 엿볼 수 있었어요. 코드와 PR 본문을 비교하며 몇 가지 질문을 준비했습니다. 스스로에게 답해보며 코드를 더 깊게 이해하는 시간을 가져보는 건 어떨까요?

  • 목표와 구현의 연결고리: 본문에 작성된 ‘서버 상태를 선언적으로 다루기’ 목표는 댓글 도메인에 잘 반영되었네요. 혹시 posts/users/tags도 Query로 전환하는 과정에서 고민했던 다른 접근(예: SWR, RTK Query, Zustand + fetch 조합)은 무엇이었나요?
  • 숨겨진 의도 파악: PostsManagerPage에서 UI를 features로 추출한 변화가 보입니다. “페이지는 오케스트레이션만 담당하도록” 리팩토링을 더 진행할 계획이 있으신가요?
  • 스스로에게 던지는 질문:
    • "이번 PR에서 내가 가장 자랑하고 싶은 코드 한 줄은 무엇이고, 그 이유는 뭘까?"
    • "컴포넌트의 추상화 수준은 적절했나요? (과도한 추상화나 불필요한 반복은 없었나요?)"
    • "Toss Frontend Fundamental의 결합도(Coupling) 원칙처럼, 컴포넌트 간 의존성을 낮추기 위해 어떤 고민을 했나요?"
    • "이 코드를 처음 보는 동료는 어떤 부분을 가장 이해하기 어려워할까?"
    • "이번에 적용한 ‘낙관적 업데이트’가 DummyJson의 비영속 환경 외 실제 서버 에러/경합 상황에서도 잘 동작하도록 설계되었을까?"

📚 참고 자료

📄 내부 문서

🌐 추천 아티클


이번 리뷰가 개발자님의 성장에 도움이 되었으면 좋겠습니다. 다음주도 화이팅 하세요! ✨

끝.

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.

2 participants