-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
🔀 로그인 페이지 리팩토링 진행 #63
Conversation
Walkthrough이 풀 리퀘스트는 사용자 인증 프로세스와 관련된 여러 파일의 리팩토링을 포함합니다. 주요 변경 사항은 React Query 훅을 사용하여 로그인, 회원가입, SMS 인증과 같은 인증 관련 기능을 모듈화하고 간소화하는 것입니다. 기존의 직접적인 API 호출 방식에서 벗어나 더 구조화되고 재사용 가능한 훅 기반의 접근 방식으로 전환했습니다. Changes
Poem
Tip CodeRabbit's docstrings feature is now available as part of our Early Access Program! Simply use the command Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 11
🧹 Nitpick comments (8)
src/entities/signIn/model/useSignin.ts (1)
6-9
: 중복된 인터페이스 제거 필요
SignInData
인터페이스가 API 파일과 중복되어 있습니다. 타입 정의를 한 곳으로 통합하여 관리하는 것이 좋습니다.
postSignin.ts
에서 인터페이스를 export하고 여기서 import하여 사용하세요:-interface SignInData { - nickname: string; - password: string; -} +import { SignInData } from '../api/postSignin';src/entities/signIn/ui/SignInForm/index.tsx (2)
21-21
: 로딩 상태 처리 개선 필요mutation의 로딩 상태를 더 효과적으로 활용할 수 있습니다.
다음과 같이 개선하는 것을 제안드립니다:
-const { mutate: signin } = useSignin(); +const { mutate: signin, isLoading } = useSignin(); - (data) => signin(data), + async (data) => { + try { + await signin(data); + } catch (error) { + // 에러 처리 + } + },그리고 버튼의 disabled 속성을 다음과 같이 수정하세요:
-<Button disabled={isSubmitting} type="submit" text="로그인" /> +<Button disabled={isSubmitting || isLoading} type="submit" text={isLoading ? "로그인 중..." : "로그인"} />Also applies to: 26-26
Line range hint
41-49
: 비밀번호 유효성 검사 개선 필요비밀번호 유효성 검사 로직을 더 명확하고 재사용 가능하게 개선할 수 있습니다.
상수와 유틸리티 함수로 분리하는 것을 추천드립니다:
+const PASSWORD_VALIDATION = { + minLength: 8, + pattern: /^(?=.*[A-Z])(?=.*[!@#$%^&*])(?=.{8,})/, + messages: { + required: '비밀번호를 입력해주세요.', + invalid: '비밀번호는 8자리 이상, 대문자 1개, 특수문자 1개 이상을 포함해야 합니다.', + }, +}; - pattern: { - value: /^(?=.*[A-Z])(?=.*[!@#$%^&*])(?=.{8,})/, - message: - '비밀번호는 8자리 이상, 대문자 1개, 특수문자 1개 이상을 포함해야 합니다.', - }, + pattern: { + value: PASSWORD_VALIDATION.pattern, + message: PASSWORD_VALIDATION.messages.invalid, + },src/entities/signUp/ui/SignUpForm/index.tsx (3)
31-36
: 훅 사용 시 의존성 관리 필요
useCheckSmsCode
훅에watch('phoneNumber')
와watch('code')
를 인자로 전달하고 있습니다. 이러한watch
함수는 컴포넌트가 렌더링될 때마다 호출되어 성능에 영향을 줄 수 있습니다. 훅 내부에서 필요한 시점에 값을 참조하도록 수정하는 것을 권장합니다.
135-135
: SMS 코드 확인 시 입력 값 검증 필요
checkSmsCode()
호출 전에phoneNumber
와code
값이 유효한지 확인하는 로직을 추가해주세요. 값이 없을 경우 예기치 않은 에러가 발생할 수 있습니다.
144-144
: SMS 전송 함수 호출 시 입력 값 전달 방식 확인
sendSms(watch('phoneNumber'))
로 전화번호를 전달하는 방식이 적절합니다. 하지만phoneNumber
값이 유효한지 확인하는 검증 로직이 추가되면 더 견고한 코드가 될 것입니다.src/entities/signUp/model/useSendSms.ts (1)
9-19
: mutation 설정 개선 필요mutation 설정에 retry 로직과 로딩 상태 처리를 추가하는 것이 좋습니다.
return useMutation({ mutationFn: (phoneNumber: string) => postSendSms(phoneNumber), + retry: 1, onSuccess: () => { setIsSmsSent(true); setTimer(180); toast.success('문자 메시지 전송이 완료되었습니다.'); }, onError: () => { toast.error('문자 메시지 전송에 실패했습니다.'); }, + onMutate: () => { + toast.info('문자 메시지를 전송중입니다...'); + } });src/entities/signUp/model/useSignup.ts (1)
6-12
: 인터페이스에 문서화를 추가하면 좋을 것 같습니다.각 필드의 용도와 제약사항을 명확히 하기 위해 JSDoc 문서화를 추가하는 것이 좋겠습니다.
다음과 같이 문서화를 추가해보세요:
+/** + * 회원가입에 필요한 사용자 데이터 인터페이스 + * @interface SignUpData + */ interface SignUpData { + /** 사용자의 실명 */ name: string; + /** 사용자의 닉네임 */ nickname: string; + /** 사용자의 이메일 주소 */ email: string; + /** 사용자의 비밀번호 */ password: string; + /** 사용자의 전화번호 */ phoneNumber: string; }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (14)
src/entities/signIn/api/postSignin.ts
(1 hunks)src/entities/signIn/model/useSignin.ts
(1 hunks)src/entities/signIn/ui/SignInForm/index.tsx
(2 hunks)src/entities/signUp/api/checkSmsCode.ts
(0 hunks)src/entities/signUp/api/getCheckSmsCode.ts
(1 hunks)src/entities/signUp/api/postSendSms.ts
(1 hunks)src/entities/signUp/api/postSignup.ts
(1 hunks)src/entities/signUp/api/sendSms.ts
(0 hunks)src/entities/signUp/api/signup.ts
(0 hunks)src/entities/signUp/model/useCheckSmsCode.ts
(1 hunks)src/entities/signUp/model/useSendSms.ts
(1 hunks)src/entities/signUp/model/useSignup.ts
(1 hunks)src/entities/signUp/model/useTimer.ts
(1 hunks)src/entities/signUp/ui/SignUpForm/index.tsx
(4 hunks)
💤 Files with no reviewable changes (3)
- src/entities/signUp/api/checkSmsCode.ts
- src/entities/signUp/api/signup.ts
- src/entities/signUp/api/sendSms.ts
🔇 Additional comments (5)
src/entities/signUp/ui/SignUpForm/index.tsx (2)
7-9
: 사용자 정의 훅을 통한 코드 모듈화
useCheckSmsCode
, useSendSms
, useSignup
훅을 임포트하여 인증 관련 로직의 재사용성과 모듈화가 향상되었습니다.
38-38
: 타이머 훅에 상태 변경 함수 추가
useTimer
훅에 setIsSmsSent
를 인자로 추가하여 타이머 종료 시 SMS 전송 상태를 관리하는 로직이 명확해졌습니다.
src/entities/signUp/model/useCheckSmsCode.ts (1)
4-10
: 사용자 정의 훅의 올바른 구현
useCheckSmsCode
훅에서 useQuery
를 적절히 활용하여 SMS 코드 검증 로직을 구현하였습니다. enabled: false
옵션을 사용하여 필요 시에만 refetch
로 호출하는 방식이 효율적입니다.
src/entities/signUp/model/useSignup.ts (2)
1-4
: 필요한 의존성들이 잘 구성되어 있습니다!
각 라이브러리의 사용 목적이 명확하고 적절합니다.
14-27
: 🛠️ Refactor suggestion
에러 처리와 사용자 경험을 개선할 수 있습니다.
현재 구현에서 몇 가지 개선할 점이 있습니다:
다음과 같이 개선해보세요:
export const useSignup = () => {
const router = useRouter();
return useMutation({
mutationFn: (data: SignUpData) => postSignup(data),
onSuccess: () => {
toast.success('회원가입이 완료되었습니다.');
- router.push('/signIn');
+ // 토스트 메시지를 볼 수 있도록 약간의 지연 후 리다이렉트
+ setTimeout(() => router.push('/signIn'), 1500);
},
- onError: () => {
- toast.error('회원가입에 실패했습니다.');
+ onError: (error: any) => {
+ const errorMessage = error?.response?.data?.message || '회원가입에 실패했습니다.';
+ toast.error(errorMessage);
},
});
};
추가로 고려할 사항:
- 로딩 상태를 사용자에게 표시
- 중복 제출 방지
- 네트워크 오류와 서버 오류를 구분하여 처리
API 응답 형식을 확인하기 위해 다음 스크립트를 실행하세요:
✅ Verification successful
Let me check the error handling implementation in the API layer to verify if we need additional error type information.
Let me check the axios configuration and error handling setup.
Let me check the API client configuration one last time.
사용자 경험 개선을 위한 제안사항입니다.
현재 구현에서 다음과 같은 개선이 필요합니다:
export const useSignup = () => {
const router = useRouter();
return useMutation({
mutationFn: (data: SignUpData) => postSignup(data),
onSuccess: () => {
toast.success('회원가입이 완료되었습니다.');
- router.push('/signIn');
+ // 토스트 메시지를 볼 수 있도록 약간의 지연 후 리다이렉트
+ setTimeout(() => router.push('/signIn'), 1500);
},
onError: () => {
toast.error('회원가입에 실패했습니다.');
},
});
};
- 토스트 메시지가 표시되기 전에 페이지가 이동되는 문제를 해결하기 위해 지연시간 추가
- 기본 에러 메시지만 사용하는 것이 적절함 (apiClient 설정과 다른 컴포넌트들의 에러 처리 패턴 확인 결과)
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# API 응답 형식 확인
rg -A 10 "postSignup" src/
Length of output: 1576
Script:
#!/bin/bash
# Check API error handling implementation
ast-grep --pattern 'catch ($_) {
$$$
}'
# Check if there are any custom error types defined
rg -g '*.ts' -g '*.tsx' 'type.*Error' src/
Length of output: 88
Script:
#!/bin/bash
# Check axios configuration and error handling
rg -g '*.ts' -g '*.tsx' "axios\.(create|interceptors)" src/
# Check if there are any common error handling utilities
fd -e ts -e tsx --exec grep -l "error\|Error" {} \; src/
Length of output: 514
Script:
#!/bin/bash
# Check API client configuration
cat src/shared/libs/apiClient.ts
# Check for any global error handling
rg -g '*.ts' -g '*.tsx' "toast\.(error|success)" src/
Length of output: 3296
export const postSignin = async (data: SignInData) => { | ||
const response = await axios.post('/api/auth/signin', data); | ||
return response; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
API 응답 타입 및 에러 처리 개선 필요
API 호출 구현에 다음 사항들이 보완되어야 합니다:
- 응답 데이터의 타입 정의가 누락되었습니다
- 에러 처리 로직이 없습니다
- axios 인터셉터 설정이 필요할 수 있습니다
다음과 같이 개선하는 것을 제안드립니다:
+interface SignInResponse {
+ accessToken: string;
+ // 기타 응답 필드들...
+}
-export const postSignin = async (data: SignInData) => {
+export const postSignin = async (data: SignInData): Promise<SignInResponse> => {
try {
- const response = await axios.post('/api/auth/signin', data);
+ const response = await axios.post<SignInResponse>('/api/auth/signin', data);
return response.data;
} catch (error) {
+ if (axios.isAxiosError(error)) {
+ throw new Error(error.response?.data?.message || '로그인에 실패했습니다');
+ }
+ throw error;
}
};
📝 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 postSignin = async (data: SignInData) => { | |
const response = await axios.post('/api/auth/signin', data); | |
return response; | |
}; | |
interface SignInResponse { | |
accessToken: string; | |
// 기타 응답 필드들... | |
} | |
export const postSignin = async (data: SignInData): Promise<SignInResponse> => { | |
try { | |
const response = await axios.post<SignInResponse>('/api/auth/signin', data); | |
return response.data; | |
} catch (error) { | |
if (axios.isAxiosError(error)) { | |
throw new Error(error.response?.data?.message || '로그인에 실패했습니다'); | |
} | |
throw error; | |
} | |
}; |
return useMutation({ | ||
mutationFn: (data: SignInData) => postSignin(data), | ||
onSuccess: () => { | ||
toast.success('로그인이 완료되었습니다.'); | ||
router.push('/'); | ||
}, | ||
onError: () => { | ||
toast.error('로그인에 실패했습니다.'); | ||
}, | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
mutation 설정 개선 필요
mutation 구성에 몇 가지 중요한 설정이 누락되었습니다:
다음 설정들을 추가하는 것을 추천드립니다:
return useMutation({
mutationFn: (data: SignInData) => postSignin(data),
+ retry: 1,
onSuccess: () => {
toast.success('로그인이 완료되었습니다.');
+ // 로그인 후 관련 쿼리들 무효화
+ queryClient.invalidateQueries({ queryKey: ['user'] });
router.push('/');
},
onError: () => {
toast.error('로그인에 실패했습니다.');
},
+ onSettled: () => {
+ // 로딩 상태 처리
+ }
});
Committable suggestion skipped: line range outside the PR's diff.
@@ -126,10 +129,10 @@ const SignUpForm = () => { | |||
type="text" | |||
placeholder="인증 번호 입력" | |||
style={{ width: '80%' }} | |||
disabled={!isSmsSent} | |||
disabled={!isSmsSent && watch('code') !== null} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
입력 필드 비활성화 조건 로직 수정 필요
disabled={!isSmsSent && watch('code') !== null}
조건에서 watch('code') !== null
은 항상 참(true)일 수 있습니다. 이는 입력 필드가 의도치 않게 비활성화되지 않는 원인이 될 수 있으므로 조건 로직을 재검토해주세요.
적용 예시:
-disabled={!isSmsSent && watch('code') !== null}
+disabled={!isSmsSent || !watch('code')}
📝 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.
disabled={!isSmsSent && watch('code') !== null} | |
disabled={!isSmsSent || !watch('code')} |
|
||
return ( | ||
<form | ||
onSubmit={handleSubmit( | ||
(data) => signUp(data, router), | ||
(data) => signup(data), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
서버로 전달되는 데이터 필터링 필요
signup
함수 호출 시 data
를 그대로 전달하고 있어 checkPassword
와 code
같은 불필요한 데이터가 서버로 보내질 수 있습니다. 민감한 정보나 불필요한 데이터는 서버로 전달되지 않도록 필요한 필드만 선별하여 전달하는 것을 권장합니다.
적용 예시:
(data) => signup({
name: data.name,
nickname: data.nickname,
email: data.email,
password: data.password,
phoneNumber: data.phoneNumber,
})
📝 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.
(data) => signup(data), | |
(data) => signup({ | |
name: data.name, | |
nickname: data.nickname, | |
email: data.email, | |
password: data.password, | |
phoneNumber: data.phoneNumber, | |
}), |
const response = await axios.post('/api/auth/sms', { phoneNumber }); | ||
return response; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
API 호출 시 에러 처리 필요
axios.post
요청 중 발생할 수 있는 에러에 대한 처리가 없습니다. 네트워크 오류나 서버 오류에 대비하기 위해 try-catch
구문을 사용하여 에러를 처리하는 것을 권장합니다.
적용 예시:
export const postSendSms = async (phoneNumber: string) => {
if (!phoneNumber) {
throw new Error('전화번호를 입력해주세요.');
}
+ try {
const response = await axios.post('/api/auth/sms', { phoneNumber });
return response;
+ } catch (error) {
+ throw error;
+ }
};
Committable suggestion skipped: line range outside the PR's diff.
export const postSignup = async (data: SignUpData) => { | ||
const response = await axios.post('/api/auth/signup', data); | ||
return response; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
API 호출 시 에러 처리 필요
axios.post
요청 시 발생할 수 있는 에러를 처리하지 않고 있습니다. 서버 응답 오류나 네트워크 장애에 대비하여 try-catch
구문으로 에러를 처리하는 것을 권장합니다.
적용 예시:
export const postSignup = async (data: SignUpData) => {
+ try {
const response = await axios.post('/api/auth/signup', data);
return response;
+ } catch (error) {
+ throw error;
+ }
};
📝 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 postSignup = async (data: SignUpData) => { | |
const response = await axios.post('/api/auth/signup', data); | |
return response; | |
export const postSignup = async (data: SignUpData) => { | |
try { | |
const response = await axios.post('/api/auth/signup', data); | |
return response; | |
} catch (error) { | |
throw error; | |
} | |
}; |
const response = await axios.get( | ||
`/api/auth/sms?phoneNumber=${phoneNumber}&code=${code}`, | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
URL 매개변수 인코딩 필요
URL 매개변수에 특수 문자가 포함될 수 있으므로 encodeURIComponent
를 사용하여 안전하게 인코딩해야 합니다.
- `/api/auth/sms?phoneNumber=${phoneNumber}&code=${code}`,
+ `/api/auth/sms?phoneNumber=${encodeURIComponent(phoneNumber)}&code=${encodeURIComponent(code)}`,
📝 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.
const response = await axios.get( | |
`/api/auth/sms?phoneNumber=${phoneNumber}&code=${code}`, | |
); | |
const response = await axios.get( | |
`/api/auth/sms?phoneNumber=${encodeURIComponent(phoneNumber)}&code=${encodeURIComponent(code)}`, | |
); |
export const getCheckSmsCode = async (phoneNumber: string, code: string) => { | ||
if (!phoneNumber || !code) { | ||
toast.error('전화번호와 인증 번호를 입력해주세요.'); | ||
return; | ||
} | ||
|
||
const response = await axios.get( | ||
`/api/auth/sms?phoneNumber=${phoneNumber}&code=${code}`, | ||
); | ||
return response; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
에러 처리 및 타입 안전성 개선 필요
함수의 반환 타입을 명시하고 에러 처리를 개선하는 것이 좋습니다.
-export const getCheckSmsCode = async (phoneNumber: string, code: string) => {
+interface SmsVerificationResponse {
+ success: boolean;
+ message: string;
+}
+
+export const getCheckSmsCode = async (
+ phoneNumber: string,
+ code: string
+): Promise<SmsVerificationResponse> => {
if (!phoneNumber || !code) {
toast.error('전화번호와 인증 번호를 입력해주세요.');
- return;
+ throw new Error('전화번호와 인증 번호는 필수입니다.');
}
- const response = await axios.get(
- `/api/auth/sms?phoneNumber=${phoneNumber}&code=${code}`,
- );
- return response;
+ try {
+ const response = await axios.get<SmsVerificationResponse>(
+ `/api/auth/sms?phoneNumber=${encodeURIComponent(phoneNumber)}&code=${encodeURIComponent(code)}`,
+ );
+ return response.data;
+ } catch (error) {
+ toast.error('인증 확인 중 오류가 발생했습니다.');
+ throw error;
+ }
📝 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 getCheckSmsCode = async (phoneNumber: string, code: string) => { | |
if (!phoneNumber || !code) { | |
toast.error('전화번호와 인증 번호를 입력해주세요.'); | |
return; | |
} | |
const response = await axios.get( | |
`/api/auth/sms?phoneNumber=${phoneNumber}&code=${code}`, | |
); | |
return response; | |
}; | |
interface SmsVerificationResponse { | |
success: boolean; | |
message: string; | |
} | |
export const getCheckSmsCode = async ( | |
phoneNumber: string, | |
code: string | |
): Promise<SmsVerificationResponse> => { | |
if (!phoneNumber || !code) { | |
toast.error('전화번호와 인증 번호를 입력해주세요.'); | |
throw new Error('전화번호와 인증 번호는 필수입니다.'); | |
} | |
try { | |
const response = await axios.get<SmsVerificationResponse>( | |
`/api/auth/sms?phoneNumber=${encodeURIComponent(phoneNumber)}&code=${encodeURIComponent(code)}`, | |
); | |
return response.data; | |
} catch (error) { | |
toast.error('인증 확인 중 오류가 발생했습니다.'); | |
throw error; | |
} | |
}; |
useEffect(() => { | ||
if (timer > 0) { | ||
const intervalId = setInterval(() => { | ||
setTimer((prev) => prev - 1); | ||
}, 1000); | ||
|
||
return () => clearInterval(intervalId); | ||
} else if (timer === 0) { | ||
setIsSmsSent(false); | ||
} | ||
}, [timer, setTimer]); | ||
}, [timer, setTimer, setIsSmsSent]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
타이머 로직 개선 필요
타이머 로직에 몇 가지 개선이 필요합니다:
useEffect(() => {
+ let intervalId: NodeJS.Timeout;
if (timer > 0) {
- const intervalId = setInterval(() => {
+ intervalId = setInterval(() => {
setTimer((prev) => prev - 1);
}, 1000);
-
- return () => clearInterval(intervalId);
} else if (timer === 0) {
setIsSmsSent(false);
}
+ return () => {
+ if (intervalId) {
+ clearInterval(intervalId);
+ }
+ };
}, [timer, setTimer, setIsSmsSent]);
- 메모리 누수 방지를 위한 cleanup 함수 개선
- 타이머가 0이 되었을 때의 처리 로직 명확화
- 인터벌 ID 관리 개선
📝 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.
useEffect(() => { | |
if (timer > 0) { | |
const intervalId = setInterval(() => { | |
setTimer((prev) => prev - 1); | |
}, 1000); | |
return () => clearInterval(intervalId); | |
} else if (timer === 0) { | |
setIsSmsSent(false); | |
} | |
}, [timer, setTimer]); | |
}, [timer, setTimer, setIsSmsSent]); | |
useEffect(() => { | |
let intervalId: NodeJS.Timeout; | |
if (timer > 0) { | |
intervalId = setInterval(() => { | |
setTimer((prev) => prev - 1); | |
}, 1000); | |
} else if (timer === 0) { | |
setIsSmsSent(false); | |
} | |
return () => { | |
if (intervalId) { | |
clearInterval(intervalId); | |
} | |
}; | |
}, [timer, setTimer, setIsSmsSent]); |
toast.success('문자 메시지 전송이 완료되었습니다.'); | ||
}, | ||
onError: () => { | ||
toast.error('문제 매시지 전송에 실패했습니다.'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
오타 수정 필요
에러 메시지의 오타를 수정해야 합니다.
- toast.error('문제 매시지 전송에 실패했습니다.');
+ toast.error('문자 메시지 전송에 실패했습니다.');
📝 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.
toast.error('문제 매시지 전송에 실패했습니다.'); | |
toast.error('문자 메시지 전송에 실패했습니다.'); |
💡 배경 및 개요
로그인 페이지 리팩토링 진행
📃 작업내용
로그인 페이지 리팩토링 진행
Summary by CodeRabbit
신규 기능
버그 수정
문서화
리팩토링