Conversation
Merge pull request #108 from THIP-TextHip/main
Update useOAuthToken.ts
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
Walkthrough라우터의 중첩된 Signup 경로를 평면화하고, API 요청형식에서 Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant Router
participant SignupNickname
participant SignupGenre
User->>Router: GET /signup
Router-->>SignupNickname: render SignupNickname
User->>Router: GET /signup/genre
Router-->>SignupGenre: render SignupGenre
sequenceDiagram
participant SignupGenre
participant API as postSignup
participant Router
SignupGenre->>API: POST /users/signup { aliasName, nickname }
API-->>SignupGenre: { success: true }
SignupGenre->>Router: navigate('/signupdone', { aliasName, nickname })
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~15 minutes Possibly related PRs
Suggested reviewers
Poem
✨ Finishing Touches
🧪 Generate unit tests
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
| <Route path="signup" element={<SignupNickname />} /> | ||
| <Route path="signup/genre" element={<SignupGenre />} /> |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
중첩 → 평면 라우트 전환은 타당하지만, 부모(Signup) 레이아웃/가드 소실 여부를 확인해주세요
이전 구조에서 Signup 컴포넌트가 공통 레이아웃(스텝 진행바, 공통 헤더 등)이나 Outlet/컨텍스트/가드 역할을 했다면, 평면 라우트로 전환되면서 해당 역할이 사라졌을 수 있습니다. 특히 /signup/genre에 직접 접근을 차단하는 가드가 빠지면 플로우가 깨질 수 있습니다.
- 확인 포인트
- Signup.tsx가
<Outlet />또는useOutletContext로 하위 스텝에 상태/가드를 제공했는지 SignupNickname/SignupGenre가 부모 컨텍스트나 레이아웃에 의존하지 않는지navigate("genre")/to="genre"등 상대 네비게이션이 여전히 기대대로 동작하는지
- Signup.tsx가
필요 시, signup/genre 라우트에 최소한의 가드를 씌워 플로우 보장을 권장합니다.
적용 예시(가드 컴포넌트가 있다는 전제):
- <Route path="signup" element={<SignupNickname />} />
- <Route path="signup/genre" element={<SignupGenre />} />
+ <Route path="signup" element={<SignupNickname />} />
+ <Route
+ path="signup/genre"
+ element={
+ <SignupGuard>
+ <SignupGenre />
+ </SignupGuard>
+ }
+ />가드 예시 구현(외부 파일; 실제 앱 상태소스에 맞게 수정 필요):
import { Navigate, useLocation } from 'react-router-dom';
// TODO: 실제 구현으로 교체(예: Redux/Zustand/Recoil/Query 등에서 닉네임 완료 여부 읽기)
function useCanProceedToGenre() {
return false;
}
export function SignupGuard({ children }: { children: React.ReactNode }) {
const canProceed = useCanProceedToGenre();
const location = useLocation();
if (!canProceed) {
return <Navigate to="/signup" replace state={{ from: location }} />;
}
return <>{children}</>;
}아래 스크립트로 잠재 리스크를 빠르게 점검할 수 있습니다.
🏁 Script executed:
#!/bin/bash
# 1) Signup 래퍼 파일 존재 여부 확인
fd -a --glob 'src/**/signup/Signup.*'
# 2) Outlet/OutletContext 의존성 확인(부모 컨텍스트 의존 여부)
rg -n -A2 -B2 $'useOutletContext|<Outlet' src
# 3) 상대 네비게이션(genre) 사용처 확인
rg -n -A1 -B1 $'navigate\\([\'"]genre[\'"]\\)|to=[\'"]genre[\'"]' srcLength of output: 361
Signup.tsx의 미사용 레이아웃 확인 및 중첩 구조 적용 여부 결정
현재 검증 결과:
src/pages/signup/Signup.tsx에<Outlet />이 존재하지만,src/pages/index.tsx의 라우트가 모두 평면 구조로 정의되어 있어 해당 레이아웃이 렌더링되지 않습니다.SignupNickname과SignupGenre양쪽 컴포넌트에서useOutletContext나 부모 상태·컨텍스트 의존 코드는 발견되지 않았습니다.navigate('genre')또는to="genre"같은 상대 경로 네비게이션도 사용되지 않고 있습니다.
해결 방향 제안:
- 부모 레이아웃/가드를 더 이상 사용하지 않을 계획이라면,
Signup.tsx와 관련 파일을 제거하거나 단일 페이지 방식으로 리팩터링하세요. - 여전히 단계별 레이아웃(스텝 진행바·헤더)이나 가드 로직이 필요하다면, 아래처럼 중첩 라우트 구조로 돌아가길 권장합니다.
<Routes>
- <Route path="signup" element={<SignupNickname />} />
- <Route path="signup/genre" element={<SignupGenre />} />
+ <Route path="signup" element={<Signup />}>
+ <Route index element={<SignupNickname />} />
+ <Route
+ path="genre"
+ element={
+ <SignupGuard>
+ <SignupGenre />
+ </SignupGuard>
+ }
+ />
+ </Route>
</Routes>필요하다면, 다음과 같은 가드 컴포넌트를 참고해 실제 앱 상태 관리 로직에 맞춰 구현하세요:
import { Navigate, useLocation } from 'react-router-dom';
function useCanProceedToGenre() {
// TODO: 닉네임 완료 여부 등을 실제 상태에서 읽어오기
return false;
}
export function SignupGuard({ children }: { children: React.ReactNode }) {
const canProceed = useCanProceedToGenre();
const location = useLocation();
return canProceed
? <>{children}</>
: <Navigate to="/signup" replace state={{ from: location }} />;
}🤖 Prompt for AI Agents
In src/pages/index.tsx around lines 47-48, the Signup parent layout
(src/pages/signup/Signup.tsx) contains an Outlet but your routes are defined
flat so that layout never renders; either remove/refactor the unused Signup
layout and related files if you don't need a multi-step layout, or convert the
routes to nested routes so the parent layout wraps the child steps: replace the
two flat signup routes with a parent Route path="signup" element={<Signup /> }
and put nested Route path="" element={<SignupNickname />} and Route path="genre"
element={<SignupGenre />} (optionally wrap child routes with a guard component
if you need step protection), and update any imports and navigation to use
absolute or relative paths consistent with nesting.
There was a problem hiding this comment.
Actionable comments posted: 1
🔭 Outside diff range comments (2)
src/pages/signup/SignupGenre.tsx (2)
34-41: 안전 폴백 추가: 히스토리 미보유 시/signup으로 이동히스토리가 없으면
navigate(-1)이 동작하지 않을 수 있으므로,window.history.length를 확인해 뒤로 갈 수 없을 땐 회원가입 첫 단계(/signup)로 폴백하도록 수정하세요.수정 대상:
- 파일:
src/pages/signup/SignupGenre.tsx- 위치: 34~41행
제안하는 코드 변경 예시:
- // nickname이 없으면 이전 페이지로 돌아가기 - if (!nickname) { - console.log('❌ nickname이 전달되지 않았습니다.'); - console.log('❌ 이전 페이지로 돌아갑니다.'); - navigate(-1); - return; - } + // nickname이 없으면 이전 페이지로 돌아가기 (폴백 포함) + if (!nickname) { + console.error('❌ nickname이 전달되지 않았습니다.'); + if (window.history.length > 1) { + navigate(-1); + } else { + // 회원가입 첫 단계 경로로 폴백 + navigate('/signup', { replace: true }); + } + return; + }
1-125: SignupDone.tsx의 상태 키 불일치(nickname vs nickName) 수정 필요SignupGenre에서
navigate('/signupdone', { state: { nickname } })로 전달한 키(nickname)와 SignupDone에서 받고 있는 키(nickName)가 달라 닉네임이 제대로 표시되지 않습니다. 아래 파일을 수정해주세요.
- 수정 대상: src/pages/signup/SignupDone.tsx
location.state에서nickName→nickname으로 변경- 코드 내 모든
nickName사용 부분을nickname으로 통일- const { nickName, aliasName } = location.state || {}; + const { nickname, aliasName } = location.state || {}; - if (!nickName || !aliasName) { + if (!nickname || !aliasName) { - <div className="title">안녕하세요, {nickName}님</div> + <div className="title">안녕하세요, {nickname}님</div> - <div className="username">{nickName}</div> + <div className="username">{nickname}</div>
/genres.json파일은public/genres.json경로에 존재하므로 fetch 경로(/genres.json)에는 문제가 없습니다.- 나머지 라우팅·상태 전파 로직은 정상 동작합니다.
🧹 Nitpick comments (6)
src/pages/signup/SignupGenre.tsx (6)
25-27: location.state 타입 명시로 안정성 향상
location.state가 any로 추론되어 오타/스키마 변경에 취약합니다. state 타입을 명시해 런타임 이슈를 줄이는 것을 권장합니다.다음 변경을 제안합니다:
import { useNavigate, useLocation } from 'react-router-dom'; +import type { Location } from 'react-router-dom'; @@ - const location = useLocation(); + const location = useLocation() as Location & { state?: { nickname?: string } }; @@ - const nickname = location.state?.nickname; + const nickname = location.state?.nickname;Also applies to: 23-23, 2-2
67-70: 객체 리터럴 단축 속성 사용으로 가독성 개선
nickname: nickname→nickname으로 단축 가능합니다.const result = await postSignup({ aliasName: selectedAlias.subTitle, - nickname: nickname, + nickname, });
75-78: 네비게이션 state도 단축 속성 사용동일하게 단축 표기를 적용하면 일관성이 좋아집니다.
navigate('/signupdone', { state: { aliasName: selectedAlias.subTitle, - nickname: nickname, + nickname, }, });
18-22: 중복 제출 방지 및 UX 개선: 로딩 상태 도입빠른 연속 클릭 시 다중 요청 가능성이 있습니다. 로딩 상태를 추가해 방지하는 것을 권장합니다.
@@ >([]); const [selectedAlias, setSelectedAlias] = useState<{ id: string; subTitle: string; } | null>(null); + const [isSubmitting, setIsSubmitting] = useState(false); @@ - const handleNextClick = async () => { + const handleNextClick = async () => { - if (!selectedAlias || !nickname) return; + if (!selectedAlias || !nickname || isSubmitting) return; console.log('=== 🚀 다음 버튼 클릭 ==='); console.log('🎭 선택된 alias:', selectedAlias); console.log('👤 nickname:', nickname); try { + setIsSubmitting(true); console.log('🚀 postSignup API 호출 시작...'); // ✅ 쿠키는 브라우저가 자동으로 전송 const result = await postSignup({ aliasName: selectedAlias.subTitle, nickname, }); @@ } catch (error) { console.error('💥 회원가입 중 오류 발생:', error); + } finally { + setIsSubmitting(false); } }; @@ - isNextActive={!!selectedAlias} + isNextActive={!!selectedAlias && !isSubmitting}Also applies to: 57-86, 96-97
46-51: fetch 취소 처리로 언마운트/전환 시 경합 및 메모리 누수 방지AbortController를 사용해 언마운트 시 fetch를 중단하는 것을 권장합니다.
- useEffect(() => { - fetch('/genres.json') - .then(res => res.json()) - .then(data => setGenres(data)) - .catch(console.error); - }, []); + useEffect(() => { + const ac = new AbortController(); + (async () => { + try { + const res = await fetch('/genres.json', { signal: ac.signal }); + const data = await res.json(); + setGenres(data); + } catch (e) { + if ((e as any)?.name !== 'AbortError') console.error(e); + } + })(); + return () => ac.abort(); + }, []);
29-44: 디버그 콘솔 로그 정리 권장현재 닉네임 등 민감 정보가 콘솔에 남습니다. 배포 시에는 제거하거나 개발 모드에서만 출력하도록 하세요.
예시:
const debug = import.meta.env.MODE !== 'production'; if (debug) { console.log('👤 nickname:', nickname); }Also applies to: 60-66
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
src/api/users/postSignup.ts(1 hunks)src/pages/signup/SignupGenre.tsx(1 hunks)
🔇 Additional comments (1)
src/api/users/postSignup.ts (1)
17-20: 전역 axios 인스턴스에 withCredentials 설정 확인됨src/api/index.ts(13)에서
withCredentials: true가 이미 설정되어 있어postSignup함수에는 별도 인증/쿠키 전송 설정이 필요 없습니다.
| export interface PostSignupRequest { | ||
| aliasName: string; | ||
| nickName: string; | ||
| nickname: string; | ||
| } |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
요청 필드명 nickName → nickname 변경 반영 👍
타입 정의가 깔끔하게 정리되었습니다. 이제 호출부 전역에서 남아있는 nickName 사용이 없는지만 확인하면 됩니다.
레거시 키워드 잔존 여부를 점검하는 스크립트입니다.
🏁 Script executed:
#!/bin/bash
# 레거시 필드명 'nickName' 사용 흔적 점검
rg -n --hidden --glob '!*dist/*' --glob '!*build/*' --glob '!*node_modules/*' '\bnickName\b' || trueLength of output: 430
레거시 필드명 nickName 사용 잔존 – 추가 변경 필요
다음 파일에서 여전히 nickName이 사용되고 있으니, 전부 nickname으로 변경해주세요:
- src/pages/signup/SignupDone.tsx:12
- src/pages/signup/SignupDone.tsx:23
- src/pages/signup/SignupDone.tsx:34
- src/pages/signup/SignupDone.tsx:41
🤖 Prompt for AI Agents
In src/api/users/postSignup.ts around lines 3 to 6 the interface still uses the
legacy field naming; change any remaining occurrences of "nickName" to
"nickname". Update this file's PostSignupRequest to use nickname and then update
the referenced UI files (src/pages/signup/SignupDone.tsx lines 12, 23, 34, 41)
to read/write the same "nickname" property so names are consistent across API
and frontend.
#️⃣연관된 이슈
📝작업 내용
스크린샷 (선택)
💬리뷰 요구사항(선택)
Summary by CodeRabbit
Refactor
Chores