feat: 커뮤니티 목록 SSR 하이드레이션 적용#545
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
1 Skipped Deployment
|
Walkthrough이 PR은 커뮤니티 게시글 목록 기능을 다층 구조로 리팩토링합니다:
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Suggested reviewers
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@apps/web/src/apis/community/postListQuery.ts`:
- Around line 8-9: communityPostListQueryKey currently returns ["postList",
boardCode, category] and treats "전체" and null as different keys; update
communityPostListQueryKey so it normalizes the category parameter by mapping the
string "전체" to null (e.g., const normalizedCategory = category === "전체" ? null :
category) before returning the tuple, ensuring all callers (including
prefetches) use the same cache key for the full list.
In `@apps/web/src/app/community/`[boardCode]/loading.tsx:
- Around line 5-8: TopDetailNavigation is fixed with height h-14 so
CommunityPageSkeleton can render underneath it during loading; update the
loading wrapper around TopDetailNavigation and CommunityPageSkeleton (the div
currently using className="w-full") to include a top offset equal to the nav
height (e.g., add pt-14 or equivalent padding/margin) so the skeleton content is
pushed below the fixed TopDetailNavigation; ensure the offset matches the nav's
h-14 to avoid overlap.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: e3dc85e5-593a-4d22-9359-41290a2dffdc
📒 Files selected for processing (13)
apps/web/src/apis/community/api.tsapps/web/src/apis/community/deletePost.tsapps/web/src/apis/community/getPostList.tsapps/web/src/apis/community/index.tsapps/web/src/apis/community/patchUpdatePost.tsapps/web/src/apis/community/postCreatePost.tsapps/web/src/apis/community/postListQuery.tsapps/web/src/apis/community/queryKeys.tsapps/web/src/app/community/[boardCode]/CommunityPageContent.tsxapps/web/src/app/community/[boardCode]/CommunityPageSkeleton.tsxapps/web/src/app/community/[boardCode]/PostCards.tsxapps/web/src/app/community/[boardCode]/loading.tsxapps/web/src/app/community/[boardCode]/page.tsx
| export const communityPostListQueryKey = (boardCode: string, category: string | null = null) => | ||
| [CommunityQueryKeys.postList, boardCode, category] as const; |
There was a problem hiding this comment.
1. 전체와 null을 같은 캐시 키로 정규화해 주세요.
지금은 같은 “전체 목록” 요청이 ["postList1", boardCode, null]와 ["postList1", boardCode, "전체"]로 나뉩니다. apps/web/src/apis/community/getPostList.ts Line 16은 기본값을 null로 두고, apps/web/src/app/community/[boardCode]/page.tsx Lines 44-48은 "전체"로 프리패치하고 있어서, 다른 호출부가 기본값을 쓰면 하이드레이션된 캐시를 재사용하지 못하고 한 번 더 요청하게 됩니다.
🔧 제안 코드
export const COMMUNITY_INITIAL_CATEGORY = "전체";
export const COMMUNITY_POST_LIST_STALE_TIME = Infinity;
export const COMMUNITY_POST_LIST_GC_TIME = 1000 * 60 * 30; // 30분
+export const normalizeCommunityPostListCategory = (category: string | null = null) =>
+ !category || category === COMMUNITY_INITIAL_CATEGORY ? null : category;
+
export const communityPostListQueryKey = (boardCode: string, category: string | null = null) =>
- [CommunityQueryKeys.postList, boardCode, category] as const;
+ [CommunityQueryKeys.postList, boardCode, normalizeCommunityPostListCategory(category)] as const;📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| export const communityPostListQueryKey = (boardCode: string, category: string | null = null) => | |
| [CommunityQueryKeys.postList, boardCode, category] as const; | |
| export const COMMUNITY_INITIAL_CATEGORY = "전체"; | |
| export const COMMUNITY_POST_LIST_STALE_TIME = Infinity; | |
| export const COMMUNITY_POST_LIST_GC_TIME = 1000 * 60 * 30; // 30분 | |
| export const normalizeCommunityPostListCategory = (category: string | null = null) => | |
| !category || category === COMMUNITY_INITIAL_CATEGORY ? null : category; | |
| export const communityPostListQueryKey = (boardCode: string, category: string | null = null) => | |
| [CommunityQueryKeys.postList, boardCode, normalizeCommunityPostListCategory(category)] as const; |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@apps/web/src/apis/community/postListQuery.ts` around lines 8 - 9,
communityPostListQueryKey currently returns ["postList", boardCode, category]
and treats "전체" and null as different keys; update communityPostListQueryKey so
it normalizes the category parameter by mapping the string "전체" to null (e.g.,
const normalizedCategory = category === "전체" ? null : category) before returning
the tuple, ensuring all callers (including prefetches) use the same cache key
for the full list.
| <div className="w-full"> | ||
| <TopDetailNavigation title="커뮤니티" /> | ||
| <CommunityPageSkeleton /> | ||
| </div> |
There was a problem hiding this comment.
1) 로딩 상태에서 상단 고정 네비게이션과 본문이 겹칠 수 있어요.
`TopDetailNavigation`가 `fixed` 높이(`h-14`)라서, 현재 구조에서는 스켈레톤 시작 영역이 네비 뒤로 들어갈 수 있습니다. 로딩 화면 래퍼에 상단 오프셋을 맞춰 주세요.
수정 예시
const CommunityLoading = () => (
- <div className="w-full">
+ <div className="w-full pt-14">
<TopDetailNavigation title="커뮤니티" />
<CommunityPageSkeleton />
</div>
);📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <div className="w-full"> | |
| <TopDetailNavigation title="커뮤니티" /> | |
| <CommunityPageSkeleton /> | |
| </div> | |
| <div className="w-full pt-14"> | |
| <TopDetailNavigation title="커뮤니티" /> | |
| <CommunityPageSkeleton /> | |
| </div> |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@apps/web/src/app/community/`[boardCode]/loading.tsx around lines 5 - 8,
TopDetailNavigation is fixed with height h-14 so CommunityPageSkeleton can
render underneath it during loading; update the loading wrapper around
TopDetailNavigation and CommunityPageSkeleton (the div currently using
className="w-full") to include a top offset equal to the nav height (e.g., add
pt-14 or equivalent padding/margin) so the skeleton content is pushed below the
fixed TopDetailNavigation; ensure the offset matches the nav's h-14 to avoid
overlap.
관련 이슈
작업 내용
HydrationBoundary로 클라이언트 React Query 캐시에 주입하도록 변경했습니다.postList쿼리도 함께 무효화했습니다.특이 사항
/community/[boardCode]는 빌드 결과에서 SSR on-demand 라우트(ƒ Dynamic)로 확인됩니다.pnpm install --frozen-lockfile --prefer-offline로 설치만 수행했으며 lockfile 변경은 없습니다.22.x)과 달라Unsupported engine경고가 출력되지만 검증은 통과했습니다.리뷰 요구사항 (선택)
useGetPostList의 query key/category 기준이 일치하는지 봐주세요.검증
pnpm --filter @solid-connect/web run lint:checkpnpm --filter @solid-connect/web run typecheck:cipnpm --filter @solid-connect/web run buildhttp://localhost:3000/community/FREE렌더링 및질문탭 전환 확인