728x90
반응형
로그인은 UI는 적었지만 분리를 안해놔서 가독성도 안좋았고 유지보수하기가 힘들었음
그래서 이제 했던 파트들은 점점 분리와 최적화에 신경을 쓰려고 한다.
export interface SignIn {
email: string;
password: string;
}
interface ErrorMessage {
message?: string;
}
const validateEmail = (email: string): boolean => {
const emailRegex = /^[\w-]+(\.[\w-]+)*@([\w-]+\.)+[a-zA-Z]{2,7}$/;
return emailRegex.test(email);
};
const validatePassword = (password: string): boolean => {
const passwordPattern = /^(?=.*\d)(?=.*[a-zA-Z]).{8,}$/;
return passwordPattern.test(password);
};
const SignInUi = () => {
const dispatch = useDispatch();
const router: NextRouter = useRouter();
const [signInState, setSignInState] = useState<SignIn>({
email: '',
password: '',
});
const [error, setError] = useState<ErrorMessage>({
message: '',
});
const signInMutation = useMutation(userLogin, {
onSuccess: (data) => {
dispatch(LOGIN_USER(data));
router.push('/');
},
onError: (error: AxiosError) => {
if (error.response && error.response.data) {
setError((prev) => ({ ...prev, password: error.response?.data }));
alert('아이디와 비밀번호를 다시 확인해주세요');
}
},
});
const moveHomeBtn = React.useCallback(() => {
router.push('/');
}, [router]);
const handleInputChange = React.useCallback(
(e: React.ChangeEvent<HTMLInputElement>) => {
const { name, value } = e.target;
setSignInState((prevSignInState) => ({
...prevSignInState,
[name]: value,
}));
},
[]
);
const handleLogin = (e: FormEvent) => {
e.preventDefault();
let errors: ErrorMessage = {};
if (!validateEmail(signInState.email)) {
if (!validatePassword(signInState.password)) {
errors.message = '아이디와 비밀번호를 다시 확인해주세요';
}
}
if (Object.keys(errors).length > 0) {
setError(errors);
return;
} else {
setError({ message: '' });
}
const sendData = {
email: signInState.email,
password: signInState.password,
};
signInMutation.mutate(sendData);
};
return (
<SignInSection>
<SignInContainer onSubmit={handleLogin}>
<MainHeadText onClick={moveHomeBtn}>HAPOOM</MainHeadText>
<SignInInput
signInState={signInState}
handleInputChange={handleInputChange}
/>
{error.message && (
<TextErrorParagraph>{error.message}</TextErrorParagraph>
)}
<SignInControls signInState={signInState} />
<SocialLogin />
</SignInContainer>
</SignInSection>
);
};
export default React.memo(SignInUi);
먼저 부분 부분으로 잘라서 컴포넌트화 시킨 후 함수도 따로 컴포넌트쪽에 맡기기로 했음
export interface SignIn {
email: string;
password: string;
}
interface ErrorMessage {
message?: string;
}
const validateEmail = (email: string): boolean => {
const emailRegex = /^[\w-]+(\.[\w-]+)*@([\w-]+\.)+[a-zA-Z]{2,7}$/;
return emailRegex.test(email);
};
const validatePassword = (password: string): boolean => {
const passwordPattern = /^(?=.*\d)(?=.*[a-zA-Z]).{8,}$/;
return passwordPattern.test(password);
};
const SignInUi = () => {
const dispatch = useDispatch();
const router: NextRouter = useRouter();
const [signInState, setSignInState] = useState<SignIn>({
email: '',
password: '',
});
const [error, setError] = useState<ErrorMessage>({
message: '',
});
const signInMutation = useMutation(userLogin, {
onSuccess: (data) => {
dispatch(LOGIN_USER(data));
router.push('/');
},
onError: (error: AxiosError) => {
if (error.response && error.response.data) {
setError((prev) => ({ ...prev, password: error.response?.data }));
alert('아이디와 비밀번호를 다시 확인해주세요');
}
},
});
const moveHomeBtn = React.useCallback(() => {
router.push('/');
}, [router]);
const handleInputChange = React.useCallback(
(e: React.ChangeEvent<HTMLInputElement>) => {
const { name, value } = e.target;
setSignInState((prevSignInState) => ({
...prevSignInState,
[name]: value,
}));
},
[]
);
const handleLogin = (e: FormEvent) => {
e.preventDefault();
let errors: ErrorMessage = {};
if (!validateEmail(signInState.email)) {
if (!validatePassword(signInState.password)) {
errors.message = '아이디와 비밀번호를 다시 확인해주세요';
}
}
if (Object.keys(errors).length > 0) {
setError(errors);
return;
} else {
setError({ message: '' });
}
const sendData = {
email: signInState.email,
password: signInState.password,
};
signInMutation.mutate(sendData);
};
return (
<SignInSection>
<SignInContainer onSubmit={handleLogin}>
<MainHeadText onClick={moveHomeBtn}>HAPOOM</MainHeadText>
<SignInInput
signInState={signInState}
handleInputChange={handleInputChange}
/>
{error.message && (
<TextErrorParagraph>{error.message}</TextErrorParagraph>
)}
<SignInControls signInState={signInState} />
<SocialLogin />
</SignInContainer>
</SignInSection>
);
};
export default React.memo(SignInUi);
프랍스가 없는 부분은 메모로 최적화를 걸고 함수들은 재생성되지않게 useCallback으로 마무리! 리렌더 되지 않는 걸 확인 후 다음 작업 가잣!
반응형
'WebDev > 항해99' 카테고리의 다른 글
실전프로젝트 인피니티 스크롤 (0) | 2023.08.29 |
---|---|
실전프로젝트 TIL (0) | 2023.08.25 |
실전프로젝트 회원가입 로직 (2) | 2023.08.21 |
로그인 ui 최적화 (0) | 2023.08.19 |
스타일컴포넌트/타입스크립트 사용 - 프랍 시 $ or as prop (0) | 2023.08.19 |