Skip to content

Conversation

@keemsebin
Copy link
Member

@keemsebin keemsebin commented Nov 27, 2024

관련 이슈

close #75

📑 작업 내용

  • Loading 컴포넌트, 스토리북 구현했습니다.
  • 기존 tanstack query를 suspense 쿼리로 변경하였습니다.

💬 리뷰 중점 사항/기타 참고 사항

  • 기존의 useQuery에서는 데이터를 불러오는 동안 로딩 상태를 관리하기 위해 로딩 상태 변수를 추가하거나 isLoading 같은 상태를 수동으로 처리해야 합니다. useSuspenseQuery를 사용하면 로딩 상태를 관리하는 코드를 작성할 필요 없이, Suspense 컴포넌트와 함께 사용할 수 있습니다!

Summary by CodeRabbit

  • New Features

    • 새로운 Loading 컴포넌트 추가: 사용자에게 로딩 상태를 표시하는 스켈레톤 UI 제공.
    • ListCard 컴포넌트의 최대 높이 조정.
  • Bug Fixes

    • Landing 컴포넌트에서 버튼 클릭 시 onNext 함수가 올바르게 호출되도록 수정.
  • Documentation

    • Loading 컴포넌트에 대한 Storybook 구성 추가.
  • Chores

    • useBookMarkListuseMarkerList 훅에서 데이터 가져오는 방식을 useSuspenseInfiniteQuery로 변경하여 사용자 경험 향상.

@keemsebin keemsebin added the feat 기능 label Nov 27, 2024
@keemsebin keemsebin self-assigned this Nov 27, 2024
@keemsebin keemsebin requested a review from houony as a code owner November 27, 2024 16:07
@coderabbitai
Copy link

coderabbitai bot commented Nov 27, 2024

Walkthrough

이 풀 리퀘스트에서는 여러 컴포넌트와 훅에 대한 변경 사항이 포함되어 있습니다. ListCard 컴포넌트의 최대 높이가 조정되었고, Loading 컴포넌트에 대한 Storybook 구성이 추가되었습니다. 또한, Loading 컴포넌트의 타입 정의가 추가되고, 새로운 Loading 컴포넌트가 구현되었습니다. Landing 컴포넌트의 버튼 클릭 핸들러가 수정되었으며, 여러 훅에서 데이터 페칭 방식이 변경되었습니다.

Changes

파일 경로 변경 요약
src/components/common/ListCard/index.tsx ListCard 컴포넌트의 최대 높이를 max-h-[65dvh]에서 max-h-[55dvh]로 조정.
src/components/common/Loading/Loading.stories.tsx Loading 컴포넌트에 대한 Storybook 메타데이터 및 기본 스토리 추가.
src/components/common/Loading/Loading.types.ts 새로운 타입 Props 추가, 선택적 속성 className 포함.
src/components/common/Loading/index.tsx 새로운 Loading 컴포넌트 추가, className prop을 받아 스타일 적용.
src/components/features/LinkForm/Landing.tsx Button 컴포넌트의 onClick 핸들러를 수정하여 onNext 함수 호출.
src/hooks/api/bookmarks/useBookMarkList.ts useInfiniteQueryuseSuspenseInfiniteQuery로 변경, youtuberProfile 속성을 선택적으로 수정.
src/hooks/api/marker/useMarkerList.ts useInfiniteQueryuseSuspenseInfiniteQuery로 변경, 페이지 크기를 7에서 20으로 증가.
src/hooks/common/useBottomFunnel.tsx Suspense 컴포넌트를 추가하여 비동기 컴포넌트의 로딩 상태 관리.

Assessment against linked issues

Objective Addressed Explanation
Loading 컴포넌트 구현 (이슈 #75)

Possibly related PRs

Suggested reviewers

  • houony

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@github-actions
Copy link

Update: 2024년 11월 28일 01시 09분 23초
Storybook 미리보기: https://6709628f8a6eec04b29d4f39-fpzfhcaqwu.chromatic.com/

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Outside diff range and nitpick comments (6)
src/components/common/Loading/Loading.types.ts (1)

1-6: 타입 정의가 명확하고 잘 구성되어 있습니다.

타입 정의가 간단하면서도 목적에 맞게 잘 작성되어 있습니다. JSDoc 주석도 포함되어 있어 좋습니다.

JSDoc 주석에 다음과 같은 사용 예시를 추가하면 더 좋을 것 같습니다:

 /**
  * Optional additional class names for customization.
+ * @example
+ * <Loading className="w-full h-full" />
  */
src/components/common/ListCard/index.tsx (1)

8-8: 높이 제한에 대한 주석 추가를 제안드립니다.

최대 높이 제한(55dvh)의 이유를 설명하는 주석을 추가하면 향후 유지보수에 도움이 될 것 같습니다.

-      className="w-full max-h-[55dvh] h-fit py-5 pl-6 pr-5 rounded-2xl bg-gray-50 overflow-y-scroll"
+      // Loading 컴포넌트를 위한 공간 확보를 위해 최대 높이를 55dvh로 제한
+      className="w-full max-h-[55dvh] h-fit py-5 pl-6 pr-5 rounded-2xl bg-gray-50 overflow-y-scroll"
src/components/common/Loading/index.tsx (1)

7-23: 성능 및 접근성 개선 제안

  1. 하드코딩된 높이값이 있어 유연성이 떨어질 수 있습니다.
  2. 애니메이션이 사용자의 선호도를 고려하지 않습니다.

다음과 같은 개선을 제안드립니다:

 <div
   className={cn(
-    'w-full max-w-md space-y-3 p-4 flex flex-col items-center justify-start',
+    'w-full max-w-md space-y-3 p-4 flex flex-col items-center justify-start',
+    '@media (prefers-reduced-motion: reduce) { .animate-pulse { animation: none; } }',
     className
   )}
+  role="status"
+  aria-busy="true"
 >
   {/* ... */}
-  <div className="w-full bg-gray-100 h-[28rem] animate-pulse rounded-lg"></div>
+  <div className="w-full bg-gray-100 min-h-[28rem] animate-pulse rounded-lg"></div>
 </div>

추가로 고려할 사항:

  • 컨텐츠 크기에 따라 동적으로 조절되는 높이값 사용
  • 사용자의 모션 축소 설정을 고려한 애니메이션 처리
src/hooks/api/bookmarks/useBookMarkList.ts (1)

1-3: 임포트 구문의 스타일 개선이 필요합니다

불필요한 빈 줄을 제거하여 임포트 구문의 일관성을 유지하는 것이 좋습니다.

다음과 같이 수정해주세요:

import { useSuspenseInfiniteQuery } from '@tanstack/react-query';
-
import { get } from '@/lib/axios';
🧰 Tools
🪛 eslint

[error] 1-1: There should be no empty line within import group

(import/order)


[error] 3-3: @/lib/axios import should occur before import of @tanstack/react-query

(import/order)

src/hooks/api/marker/useMarkerList.ts (1)

1-3: import 구문 정리가 필요합니다

import 구문 사이의 불필요한 빈 줄을 제거하고 그룹화하는 것이 좋습니다.

다음과 같이 수정하는 것을 제안합니다:

import { useSuspenseInfiniteQuery } from '@tanstack/react-query';
-
import { get } from '@/lib/axios';
🧰 Tools
🪛 eslint

[error] 1-1: There should be no empty line within import group

(import/order)


[error] 3-3: @/lib/axios import should occur before import of @tanstack/react-query

(import/order)

src/components/features/LinkForm/Landing.tsx (1)

26-26: onClick 핸들러 최적화 제안

불필요한 화살표 함수 래퍼를 제거하여 성능을 개선할 수 있습니다.

다음과 같이 변경하는 것을 추천드립니다:

-<Button variant="primary" size="large" onClick={() => onNext()} className="w-full">
+<Button variant="primary" size="large" onClick={onNext} className="w-full">

이렇게 하면 렌더링할 때마다 새로운 함수를 생성하지 않아도 됩니다.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 6a033cf and 13fe07e.

📒 Files selected for processing (8)
  • src/components/common/ListCard/index.tsx (1 hunks)
  • src/components/common/Loading/Loading.stories.tsx (1 hunks)
  • src/components/common/Loading/Loading.types.ts (1 hunks)
  • src/components/common/Loading/index.tsx (1 hunks)
  • src/components/features/LinkForm/Landing.tsx (1 hunks)
  • src/hooks/api/bookmarks/useBookMarkList.ts (2 hunks)
  • src/hooks/api/marker/useMarkerList.ts (2 hunks)
  • src/hooks/common/useBottomFunnel.tsx (2 hunks)
✅ Files skipped from review due to trivial changes (1)
  • src/components/common/Loading/Loading.stories.tsx
🧰 Additional context used
🪛 eslint
src/hooks/api/bookmarks/useBookMarkList.ts

[error] 1-1: There should be no empty line within import group

(import/order)

src/hooks/api/marker/useMarkerList.ts

[error] 1-1: There should be no empty line within import group

(import/order)

🔇 Additional comments (8)
src/components/common/ListCard/index.tsx (1)

8-8: 높이 조정이 UI에 미치는 영향을 확인해주세요.

컴포넌트의 최대 높이가 65dvh에서 55dvh로 감소되었습니다. 이 변경이 다음 사항들에 영향을 미치지 않는지 확인이 필요합니다:

  • 스크롤 동작
  • 콘텐츠 가시성
  • 전체 레이아웃 구성
✅ Verification successful

ListCard 높이 변경은 안전하게 적용 가능합니다.

ListCard 컴포넌트는 다음 컴포넌트들에서 리스트 컨테이너로 사용되고 있습니다:

  • ExtractedPlacesList: 추출된 장소 목록
  • SearchResultsList: 검색 결과 목록
  • BookmarkSelectionList: 북마크 선택 목록
  • BookmarkDetail: 북마크 상세 보기
  • BookmarkList: 북마크 목록

모든 사용처에서 ListCard의 높이는 자체적으로 스크롤이 가능한 컨테이너로 사용되며, 다른 컴포넌트에서 추가적인 높이 제약이나 의존성이 없습니다. 55dvh로의 높이 감소는 콘텐츠의 스크롤 가능성을 유지하면서 안전하게 적용될 수 있습니다.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for other components that might be affected by this height change

# Search for components that might depend on ListCard's height
rg -l "ListCard" --type tsx

# Look for any height-related styles that might conflict
rg "max-h-\[(\d+)dvh\]" --type tsx

Length of output: 120


Script:

#!/bin/bash
# Search for ListCard usage without file type restriction
rg -l "ListCard"

# Look for height-related styles
rg "max-h-\["

Length of output: 950


Script:

#!/bin/bash
# Check the content of files using ListCard to understand the usage context
rg -A 5 "ListCard" src/components/features/ExtractedPlacesList/ExtractedPlacesList.tsx src/components/features/SearchResultsList/SearchResultsList.tsx src/components/features/SearchResultsList/BookmarkSelectionList.tsx src/components/features/BookmarkDetail/BookmarkDetail.tsx src/components/features/BookmarkList/BookmarkList.tsx

Length of output: 9566

src/components/common/Loading/index.tsx (1)

1-3: 깔끔한 import 구조입니다!

타입을 별도 파일로 분리하고, 유틸리티 함수를 적절히 가져오는 구조가 좋습니다.

src/hooks/api/bookmarks/useBookMarkList.ts (2)

15-15: youtuberProfile 필드의 선택적 처리에 대한 검증이 필요합니다

youtuberProfile을 선택적 필드로 변경하면 기존 코드에 영향을 미칠 수 있습니다. 이 필드를 사용하는 모든 컴포넌트에서 undefined 처리가 되어있는지 확인이 필요합니다.

다음 스크립트로 영향을 받는 컴포넌트를 확인해보세요:

✅ Verification successful

Let me check how youtuberProfile is being used in these components.


youtuberProfile 필드의 선택적 처리가 안전하게 구현되어 있습니다

모든 컴포넌트에서 youtuberProfile이 undefined일 경우를 적절히 처리하고 있습니다:

  • Profile 컴포넌트: 조건부 렌더링 (item.youtuberProfile ?)으로 안전하게 처리
  • ExtractedPlacesList 컴포넌트: 조건부 렌더링과 fallback (data.youtuberProfile || '') 모두 구현
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# youtuberProfile 필드를 사용하는 모든 컴포넌트 검색
rg -l "youtuberProfile" src/components/

Length of output: 197


Script:

#!/bin/bash
# Check usage of youtuberProfile in the components
rg "youtuberProfile" src/components/ -A 2 -B 2

Length of output: 2227


Line range hint 23-32: Suspense 기반 쿼리로의 전환이 잘 이루어졌습니다

useSuspenseInfiniteQuery로의 전환이 적절하게 이루어졌습니다. 다만, 상위 컴포넌트에서 적절한 Suspense와 ErrorBoundary 설정이 필요합니다.

다음 스크립트로 Suspense 설정을 확인해보세요:

src/hooks/api/marker/useMarkerList.ts (1)

31-42: Suspense 적용과 페이지 크기 변경에 대한 검토가 필요합니다

useSuspenseInfiniteQuery로의 전환은 로딩 상태 관리를 개선하는 좋은 변경사항입니다. 하지만 페이지 크기가 7에서 20으로 증가한 것에 대해 몇 가지 고려사항이 있습니다.

  1. 페이지 크기 증가로 인한 성능 영향을 확인해주세요:
    • 초기 로딩 시간
    • 데이터 전송량
    • 서버 부하

다음 스크립트로 페이지 크기 관련 다른 API 엔드포인트의 구현을 확인할 수 있습니다:

  1. Suspense 경계가 적절히 설정되어 있는지 확인이 필요합니다:
✅ Verification successful

Let me gather more information about the Suspense implementation and loading states.


Let me check for infinite queries with a different pattern and error handling implementation.


페이지 크기 변경과 Suspense 적용이 적절히 구현되었습니다

코드베이스 분석 결과, 다음과 같은 이유로 변경사항이 적절합니다:

  1. useBookMarkList는 페이지 크기 7을 유지하고 있는 반면, useMarkerList만 20으로 증가했습니다. 이는 마커 목록의 특성을 고려한 의도적인 설계로 보입니다.

  2. Suspense 구현이 적절히 되어있습니다:

    • useBottomFunnel 컴포넌트에서 <Suspense fallback={<Loading />}>으로 로딩 상태를 처리
    • BookmarkDetail 컴포넌트에서 무한 스크롤과 함께 잘 통합되어 있음
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# API 엔드포인트의 페이지 크기 설정을 검색
rg -g "*.ts" -g "*.js" "size=" ./src

Length of output: 263


Script:

#!/bin/bash
# Suspense 컴포넌트 사용 검색
ast-grep --pattern 'Suspense'

Length of output: 246


Script:

#!/bin/bash
# Check where the marker list is being used
rg -g "*.tsx" -g "*.ts" "useMarkerList" -A 3

Length of output: 1236


Script:

#!/bin/bash
# Check loading states and error boundaries
ast-grep --pattern 'ErrorBoundary'

Length of output: 34


Script:

#!/bin/bash
# Check if there are any other infinite queries with different page sizes
ast-grep --pattern 'useInfiniteQuery|useSuspenseInfiniteQuery'

Length of output: 64


Script:

#!/bin/bash
# Check infinite query implementations with context
rg -g "*.ts" -g "*.tsx" "useInfiniteQuery|useSuspenseInfiniteQuery" -B 2 -A 5

Length of output: 2162


Script:

#!/bin/bash
# Look for error handling patterns
rg -g "*.tsx" "onError|ErrorBoundary|error=" -B 1 -A 3

Length of output: 56


Script:

#!/bin/bash
# Check the BookmarkDetail component implementation
cat src/components/features/BookmarkDetail/BookmarkDetail.tsx

Length of output: 4590

src/hooks/common/useBottomFunnel.tsx (3)

1-13: 임포트 구조가 개선되었습니다!

절대 경로를 사용하도록 변경하고 필요한 컴포넌트들을 추가한 것이 좋습니다. 특히:

  • Suspense 추가로 로딩 상태 관리가 가능해졌습니다
  • 절대 경로 사용으로 유지보수성이 향상되었습니다

80-80: Suspense 구현이 잘 되었습니다!

stepComponents를 Suspense로 감싸고 Loading 컴포넌트를 폴백으로 사용한 것이 좋습니다. 이를 통해:

  • 로딩 상태 관리가 자동화되었습니다
  • 사용자 경험이 개선되었습니다

80-80: Loading 컴포넌트 테스트 검증이 필요합니다.

Loading 컴포넌트가 다양한 상황에서 제대로 동작하는지 확인이 필요합니다.


import { Props } from './Loading.types';

export const Loading = ({ className }: Props) => {
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

접근성 개선을 위한 제안

로딩 상태를 스크린 리더에게 알리는 것이 좋습니다.

다음과 같이 aria 속성을 추가하는 것을 제안드립니다:

-export const Loading = ({ className }: Props) => {
+export const Loading = ({ className, "aria-label": ariaLabel = "로딩 중" }: Props) => {

그리고 Props 타입도 업데이트해 주세요:

interface Props {
  className?: string;
  "aria-label"?: string;
}

@keemsebin keemsebin merged commit 6e352e1 into main Nov 30, 2024
5 checks passed
@keemsebin keemsebin deleted the feat/#75-loading branch November 30, 2024 10:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feat 기능

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEAT] Loading 컴포넌트

3 participants