likeornament 님의 블로그
Next.js 프로젝트에서 학습 & 복습 페이지 컴포넌트 재사용하기 본문
개발자 AI 교육 서비스를 개발하면서, 학습 페이지와 복습 페이지에서 같은 컴포넌트를 어떻게 재사용할지 고민한 경험이 있다.
이번 글에서는 내가 겪었던 문제와 해결 과정을 공유하며, 폴더 구조 정리, 컨테이너 패턴, props 분기 활용 방법을 정리하겠다.
1. 프로젝트 구조와 문제 상황

프로젝트에는 총 4가지 학습 기능과, 이 기능들을 복습할 수 있는 복습(review) 기능이 있다.
- 학습 기능: word(개발 용어) / knowledge(개발/CS 지식) / pr(모의 PR) / interview(모의 면접)
- 복습 기능: review




각 학습 기능은 /app/(afterLogin) 하위 경로로 구성되어 있으며,
- word와 knowledge는 안내 화면을,
- pr과 interview는 추천 PR/주제 선택 화면을 보여주도록 설계했다.
각 기능의 학습 페이지는 /learn 하위 경로로 구성되어 있으며,
페이지 전용 컴포넌트들은 _component 폴더 안에 두었다.
app/(afterLogin)/
├─ word
│ ├─ _component
│ ├─ learn
│ └─ page.tsx
├─ knowledge
│ ├─ _component
│ ├─ learn
│ └─ page.tsx
├─ pr
│ ├─ _component
│ ├─ learn
│ └─ page.tsx
├─ interview
│ ├─ _component
│ ├─ learn
│ └─ page.tsx
└─ review
└─ page.tsx
문제 상황

복습 페이지에서 사용자가 특정 기능(word 등)을 선택하면, 기존 학습 페이지의 컴포넌트를 재사용해야 했다.
하지만 /review에서 각 기능의 컴포넌트를 사용하려면, /review 내부가 아닌 /word, /knowledge, /pr, /interview 폴더 안의 _component에서 가져와야 했다.
- 이 경우, 각 페이지에서 사용하는 컴포넌트를 하위 _component에 정리하는 일관성이 깨지게 된다.
- 반대로 /app/(afterLogin)의 공용 _component 폴더에 모든 기능 컴포넌트를 모으면 관리가 복잡.
2. 해결 방법
2-1. 각 기능별 review 폴더 생성
app/(afterLogin)/
├─ word
│ ├─ _component
│ ├─ learn
│ ├─ review
│ │ └─ page.tsx
│ └─ page.tsx
├─ knowledge
│ ├─ _component
│ ├─ learn
│ ├─ review
│ │ └─ page.tsx
│ └─ page.tsx
├─ pr
│ ├─ _component
│ ├─ learn
│ ├─ review
│ │ └─ page.tsx
│ └─ page.tsx
├─ interview
│ ├─ _component
│ ├─ learn
│ ├─ review
│ │ └─ page.tsx
│ └─ page.tsx
└─ review
└─ page.tsx
- 이렇게 각 기능 안에 review 폴더를 추가했다.
- /review에서 특정 기능을 선택하면, 각 기능의 review(복습) 페이지로 라우팅
2-2. 컴포넌트 위치 통일
- 기존: /word/learn/_component
- 변경: /word/_component
→ learn과 review 페이지 모두 동일한 컴포넌트를 참조 가능
2-3. 컨테이너 컴포넌트 활용
// /word/learn/page.tsx
export default function WordLearnPage() {
return (
<Suspense fallback={
<div className="flex justify-center items-center w-full h-screen">
<LoadingSpinner size={"md"}/>
</div>
}>
<WordLearningContainer isReview={false}/>
</Suspense>
)
}
- WordLearningContainer 같은 상위 컨테이너를 만들어 공통 UI와 로직을 관리한다.
<WordLearningContainer isReview={false} /> // learn 페이지
<WordLearningContainer isReview={true} /> // review 페이지
- isReview props로 학습/복습 페이지 동작을 분기 시킨다.
2-4. Suspense 적용
- 페이지 단위에서 Suspense와 공통 로딩 컴포넌트를 적용해 일관된 로딩 UX를 제공한다.
3. 결과
- 컴포넌트 재사용성 확보 → learn과 review 페이지에서 동일한 컴포넌트를 재사용 가능
- 폴더 구조 깔끔 → 기능별 폴더 안 _component 유지
- 코드 중복 최소화 → 상위 컨테이너와 props 분기 활용
- 유지보수 용이 → 기능 추가/수정 시 일관된 구조 사용 가능
이 구조로 복습 페이지를 추가했더라도 기존 컴포넌트를 그대로 재사용하면서,
프로젝트 구조를 깔끔하게 유지할 수 있었다.
'공부' 카테고리의 다른 글
| 콘텐츠 표시 완료 시간 58% 감소, 로딩 스피너 100% 제거 — prefetch가 바꾼 UX (0) | 2025.09.05 |
|---|---|
| Tanstack Query(React Query)에 대해 알아보자 (2) | 2024.12.31 |
| Auth.js(NextAuth.js) 사용법 (2) | 2024.12.30 |