기존에 부트캠프에서 진행했던 프로젝트를 기반으로 전반적인 구조를 리팩토링하는 프로젝트입니다.
단순한 코드 개선을 넘어, 부족했던 부분은 보완하고 잘 만들어진 구조는 적극적으로 차용하여 더 완성도 높은 서비스로 발전시키는 것을 목표로 합니다.
또한 이번 프로젝트에서는 단순 구현에 그치지 않고,
이전에 놓쳤던 개념이나 이해가 부족했던 부분들을 다시 짚으며 기술적 이해도를 확실히 높이는 것에 집중합니다.
1. 상태 관리
2. 서버 통신
3. 테스트 코드 작성
App Router에서는 기본적으로 fetch 기반의 캐싱이 제공됩니다.(물론 뭐 설정 등에 따라 또 달라지지만)
하지만 다음과 같은 경우에는 한계가 있습니다.
그래서 이번 프로젝트에서는 다음과 같은 역할 분리를 선택했습니다:
핵심은
서버에서 미리 데이터를 준비하고, 클라이언트에서 그대로 재사용하는 구조입니다.
서버 컴포넌트에서 React Query를 이용해 데이터를 미리 가져옵니다.
const queryClient = new QueryClient()
await queryClient.prefetchQuery({
queryKey: ['posts'],
queryFn: getPosts,
})
👉 이 단계에서 데이터는 React Query 캐시에 저장된 상태입니다.
<HydrationBoundary state={dehydrate(queryClient)}>
<Posts />
</HydrationBoundary>
서버에서 만든 캐시를
직렬화해서 클라이언트로 전달
👉 이 과정이 없으면 클라이언트는 다시 요청하게 됩니다.
'use client'
const { data } = useQuery({
queryKey: ['posts'],
queryFn: getPosts,
})
이미 캐시가 존재하기 때문에
즉시 데이터 사용 가능
이후 필요하면 자동으로 refetch
1. 빠른 초기 렌더링
서버에서 데이터 준비 → 바로 렌더링
2. 네트워크 요청 최소화
Hydration을 통해 초기 중복 요청을 줄일 수 있으며, staleTime 설정에 따라 백그라운드 재검증 여부를 제어할 수 있음
3. 자연스러운 UX
캐시된 데이터 즉시 표시
백그라운드에서 최신 데이터 갱신 (SWR 패턴)
4. 상태 공유
props drilling 없이 useQuery로 데이터 접근
위에서 말했듯이 모든 데이터에 사용하는 것은 오히려 비효율적입니다.
1. 코드 스타일 관리
2. 디자인 시스템 기초 작업