지원서 입력값을 localStorage에 저장하여 임시 보관 기능 구현#582
Conversation
- 초기 답변 배열(initialAnswers)을 인자로 받을 수 있도록 훅 개선 - 지원서 작성 시 로컬스토리지 값을 주입할 수 있게 확장
- useAnswers 훅에 로컬스토리지에서 불러온 초기값 주입 - answers 상태가 변경될 때마다 localStorage에 자동 저장 - 제출 성공 시 localStorage 값 삭제
|
Warning
|
| 파일/경로 | 변경 요약 |
|---|---|
| frontend/src/hooks/useAnswers.ts | useAnswers 훅이 초기 답변 배열 파라미터를 받도록 수정, 일부 함수 타입 명시 및 코드 간소화 |
| frontend/src/pages/ApplicationFormPage/ApplicationFormPage.tsx | localStorage를 통한 답변 임시 저장/복원 로직 추가, 에러 처리 및 컨트롤 플로우 개선, 불필요 코드 제거 |
Sequence Diagram(s)
sequenceDiagram
participant User
participant ApplicationFormPage
participant localStorage
participant useAnswers
User->>ApplicationFormPage: 페이지 진입
ApplicationFormPage->>localStorage: clubId로 저장된 answers 조회
ApplicationFormPage->>useAnswers: 초기 answers로 훅 초기화
User->>ApplicationFormPage: 답변 입력
ApplicationFormPage->>useAnswers: 답변 상태 업데이트
useAnswers-->>ApplicationFormPage: 최신 answers 반환
ApplicationFormPage->>localStorage: answers 변경 시 저장
User->>ApplicationFormPage: 지원서 제출
ApplicationFormPage->>localStorage: answers 삭제
Estimated code review effort
🎯 3 (Moderate) | ⏱️ ~15 minutes
Possibly related issues
- Moadong/moadong#578: 본 PR은 useAnswers 훅의 초기값 처리와 localStorage 임시 저장 기능을 구현하여 해당 이슈의 목적을 직접적으로 달성합니다.
- [feature] MOA-108 지원서 입력값을 localStorage에 저장하여 임시 보관 기능 구현 #581: 지원서 입력값을 localStorage에 임시 저장하는 기능 구현과 직접적으로 연관되어 있습니다.
Possibly related PRs
- [feature] 동아리 지원하기 기능 #536: useAnswers 훅의 answer 프로퍼티 변경 및 반환값 확장 등, 동일 훅과 데이터 처리 방식에 대한 관련 변경이 있습니다.
- [feature] 동아리 지원서 답변 화면 구현 및 관련 컴포넌트 개발 #490: useAnswers 훅과 답변 관리 로직의 기반을 다룬 PR로, 본 PR의 변경과 직접적으로 연관됩니다.
- [release] v1.0.6 #508: application 생성/응답 시스템 전체 도입 PR로, useAnswers 및 관련 컴포넌트와 직접적으로 연결됩니다.
Suggested reviewers
- seongwon030
- lepitaaar
Note
⚡️ Unit Test Generation is now available in beta!
Learn more here, or try it out under "Finishing Touches" below.
✨ Finishing Touches
- 📝 Generate Docstrings
🧪 Generate unit tests
- Create PR with unit tests
- Post copyable unit tests in a comment
- Commit unit tests in branch
feature/#581-application-form-localstorage-MOA-108
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.
🪧 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.Explain this complex logic.Open a follow-up GitHub issue for this discussion.
- Files and specific lines of code (under the "Files changed" tab): Tag
@coderabbitaiin a new review comment at the desired location with your query. Examples:@coderabbitai explain this code block.@coderabbitai modularize this function.
- PR comments: Tag
@coderabbitaiin 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 explain its main purpose.@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.
Support
Need help? Create a ticket on our support page for assistance with any issues or questions.
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 pauseto pause the reviews on a PR.@coderabbitai resumeto resume the paused reviews.@coderabbitai reviewto trigger an incremental review. This is useful when automatic reviews are disabled for the repository.@coderabbitai full reviewto do a full review from scratch and review all the files again.@coderabbitai summaryto regenerate the summary of the PR.@coderabbitai generate docstringsto generate docstrings for this PR.@coderabbitai generate sequence diagramto generate a sequence diagram of the changes in this PR.@coderabbitai generate unit teststo generate unit tests for this PR.@coderabbitai resolveresolve all the CodeRabbit review comments.@coderabbitai configurationto show the current CodeRabbit configuration for the repository.@coderabbitai helpto get help.
Other keywords and placeholders
- Add
@coderabbitai ignoreanywhere in the PR description to prevent this PR from being reviewed. - Add
@coderabbitai summaryto generate the high-level summary at a specific location in the PR description. - Add
@coderabbitaianywhere 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.
✅ Deploy Preview for moadong ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (2)
frontend/src/pages/ApplicationFormPage/ApplicationFormPage.tsx (2)
35-41: 훅 호출은 올바르지만 조건부 실행 문제 존재훅 호출 자체는 올바르게 구현되어 있으나, 앞선 조기 리턴으로 인해 조건부로 실행되는 문제가 있습니다.
43-45: localStorage 저장 로직은 올바르나 조건부 실행 문제 존재답변 변경 시 localStorage에 저장하는 로직은 올바르게 구현되어 있으나, 조기 리턴으로 인한 조건부 실행 문제가 있습니다.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
frontend/src/hooks/useAnswers.ts(2 hunks)frontend/src/pages/ApplicationFormPage/ApplicationFormPage.tsx(3 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
frontend/**/*.{ts,tsx}
📄 CodeRabbit Inference Engine (frontend/.cursorrules)
frontend/**/*.{ts,tsx}: Replace magic numbers with named constants for clarity.
Replace complex or nested ternary operators with if/else statements or IIFEs for readability.
Assign complex boolean conditions to named variables.
Use consistent return types for similar functions and hooks.
Avoid hidden side effects; functions should only perform actions implied by their signature (Single Responsibility Principle).
Use unique, descriptive names for custom wrappers and functions to avoid ambiguity.
Define constants near related logic or ensure names link them clearly.
Files:
frontend/src/hooks/useAnswers.tsfrontend/src/pages/ApplicationFormPage/ApplicationFormPage.tsx
frontend/**/*.tsx
📄 CodeRabbit Inference Engine (frontend/.cursorrules)
frontend/**/*.tsx: Abstract complex logic/interactions into dedicated components or higher-order components (HOCs).
Separate significantly different conditional UI/logic into distinct components.
Colocate simple, localized logic or use inline definitions to reduce context switching.
Choose field-level or form-level cohesion based on form requirements.
Break down broad state management into smaller, focused hooks or contexts.
Use component composition instead of props drilling.
Files:
frontend/src/pages/ApplicationFormPage/ApplicationFormPage.tsx
🧠 Learnings (1)
frontend/src/pages/ApplicationFormPage/ApplicationFormPage.tsx (9)
Learnt from: seongwon030
PR: #195
File: frontend/src/pages/AdminPage/AdminPage.tsx:7-7
Timestamp: 2025-03-19T05:18:07.818Z
Learning: AdminPage.tsx에서 현재 하드코딩된 클럽 ID('67d2e3b9b15c136c6acbf20b')는 로그인 기능 구현 후 동적으로 가져오는 방식으로 수정될 예정입니다.
Learnt from: CR
PR: Moadong/moadong#0
File: frontend/.cursorrules:0-0
Timestamp: 2025-07-19T05:09:10.702Z
Learning: Applies to frontend/**/*.tsx : Choose field-level or form-level cohesion based on form requirements.
Learnt from: lepitaaar
PR: #406
File: backend/src/main/java/moadong/club/service/ClubApplyService.java:34-38
Timestamp: 2025-05-19T05:45:52.957Z
Learning: The code duplication between createClubApplication and editClubApplication methods in ClubApplyService.java is acknowledged but will be addressed in a future refactoring, as per the developer's plan.
Learnt from: CR
PR: Moadong/moadong#0
File: frontend/.cursorrules:0-0
Timestamp: 2025-07-19T05:09:10.702Z
Learning: Applies to frontend/**/*.tsx : Separate significantly different conditional UI/logic into distinct components.
Learnt from: CR
PR: Moadong/moadong#0
File: frontend/.cursorrules:0-0
Timestamp: 2025-07-19T05:09:10.702Z
Learning: Applies to frontend/**/*.tsx : Colocate simple, localized logic or use inline definitions to reduce context switching.
Learnt from: CR
PR: Moadong/moadong#0
File: frontend/.cursorrules:0-0
Timestamp: 2025-07-19T05:09:10.702Z
Learning: Applies to frontend/**/*.tsx : Abstract complex logic/interactions into dedicated components or higher-order components (HOCs).
Learnt from: CR
PR: Moadong/moadong#0
File: frontend/.cursorrules:0-0
Timestamp: 2025-07-19T05:09:10.702Z
Learning: Applies to frontend/**/*.tsx : Break down broad state management into smaller, focused hooks or contexts.
Learnt from: CR
PR: Moadong/moadong#0
File: frontend/.cursorrules:0-0
Timestamp: 2025-07-19T05:09:10.702Z
Learning: Applies to frontend/**/*.tsx : Use component composition instead of props drilling.
Learnt from: seongwon030
PR: #541
File: frontend/src/pages/ClubDetailPage/components/ClubDetailHeader/ClubDetailHeader.tsx:41-43
Timestamp: 2025-07-20T11:48:50.207Z
Learning: moadong 프로젝트는 Next.js가 아닌 순수 React + react-router-dom 기반의 CSR(Client-Side Rendering) SPA이므로, window 객체 사용에 대한 SSR 호환성 문제를 제기하지 않아야 합니다.
🧬 Code Graph Analysis (2)
frontend/src/hooks/useAnswers.ts (1)
frontend/src/types/application.ts (1)
AnswerItem(55-58)
frontend/src/pages/ApplicationFormPage/ApplicationFormPage.tsx (5)
frontend/src/hooks/useAnswers.ts (1)
useAnswers(4-33)frontend/src/hooks/queries/club/useGetClubDetail.ts (1)
useGetClubDetail(6-20)frontend/src/hooks/queries/application/useGetApplication.ts (1)
useGetApplication(4-10)frontend/src/hooks/useValidateAnswers.ts (1)
validateAnswers(3-14)frontend/src/apis/application/applyToClub.ts (1)
applyToClub(4-34)
🪛 Biome (2.1.2)
frontend/src/pages/ApplicationFormPage/ApplicationFormPage.tsx
[error] 33-33: This hook is being called conditionally, but all hooks must be called in the exact same order in every component render.
Hooks should not be called after an early return.
For React to preserve state between calls, hooks needs to be called unconditionally and always in the same order.
See https://reactjs.org/docs/hooks-rules.html#only-call-hooks-at-the-top-level
(lint/correctness/useHookAtTopLevel)
[error] 35-35: This hook is being called conditionally, but all hooks must be called in the exact same order in every component render.
Hooks should not be called after an early return.
For React to preserve state between calls, hooks needs to be called unconditionally and always in the same order.
See https://reactjs.org/docs/hooks-rules.html#only-call-hooks-at-the-top-level
(lint/correctness/useHookAtTopLevel)
[error] 41-41: This hook is being called conditionally, but all hooks must be called in the exact same order in every component render.
Hooks should not be called after an early return.
For React to preserve state between calls, hooks needs to be called unconditionally and always in the same order.
See https://reactjs.org/docs/hooks-rules.html#only-call-hooks-at-the-top-level
(lint/correctness/useHookAtTopLevel)
[error] 43-43: This hook is being called conditionally, but all hooks must be called in the exact same order in every component render.
Hooks should not be called after an early return.
For React to preserve state between calls, hooks needs to be called unconditionally and always in the same order.
See https://reactjs.org/docs/hooks-rules.html#only-call-hooks-at-the-top-level
(lint/correctness/useHookAtTopLevel)
🔇 Additional comments (7)
frontend/src/hooks/useAnswers.ts (3)
4-5: 초기값 매개변수 추가로 유연성 향상
initialAnswers매개변수 추가로 localStorage에서 복원된 데이터로 상태를 초기화할 수 있게 되었습니다. 기본값 설정으로 기존 사용법과의 호환성도 유지됩니다.
10-10: ES6 단축 속성 표기법으로 코드 간소화객체 생성 시 단축 속성 표기법을 사용하여 코드가 더 간결해졌습니다.
29-29: 명시적 반환 타입으로 타입 안전성 향상
getAnswersById함수에 명시적인 반환 타입string[]을 추가하여 타입 안전성과 코드 가독성이 개선되었습니다.frontend/src/pages/ApplicationFormPage/ApplicationFormPage.tsx (4)
1-1: localStorage 기능을 위한 useEffect 임포트 추가localStorage에 답변을 저장하는 기능을 위해
useEffect훅을 올바르게 임포트했습니다.
48-60: 에러 처리 및 사용자 경험 개선에러 발생 시 사용자에게 알림을 제공하고 클럽 페이지로 이동시키는 처리가 추가되었습니다. 데이터 로딩 실패 시에도 친화적인 메시지를 표시하여 사용자 경험이 개선되었습니다.
75-78: 스크롤 처리 로직 간소화불필요한 undefined 체크를 제거하여 코드가 더 간결하고 명확해졌습니다.
91-92: 성공적인 제출 후 localStorage 정리답변 제출 성공 후 임시 저장된 데이터를 localStorage에서 제거하는 로직이 올바르게 구현되었습니다. 실패 시에는 데이터를 보존하여 사용자가 다시 시도할 수 있도록 합니다.

#️⃣ 연관된 이슈
📝 작업 내용
1. useAnswers 훅 개선
useAnswers훅에 초기 답변 배열(initialAnswers)을 인자로 받을 수 있도록 개선했습니다.2. AnswerApplicationForm 임시 저장 기능 구현
AnswerApplicationForm에서 임시 저장 기능을 구현했습니다.localStorage에 자동 저장합니다.clubId를 기준으로 고유한 키(applicationAnswers_${clubId})로 저장합니다.3. 코드 구조 개선
🫡 참고사항
AnswerApplicationForm에서 localStorage 관련 key는"applicationAnswers_${clubId}"형식을 사용했습니다.Summary by CodeRabbit
신규 기능
버그 수정