❗️ 문제
로그인과 회원가입 페이지의 뷰 컴포넌트를 하나로 사용하고 있었기 때문에 폼이 submit 됐을 때 어떤 페이지에서 렌더링 된 건지에 따라서 서로 다른 API 전송 함수를 서로 다른 props로 보내서 트리거했었다.
// submit 되면 실행되는 함수.
const onValid = (data) => {
if (signUp) {
handleSignUp(data);
} else {
handleLogIn(data);
}
};
하지만 하나의 props로 통일해도 된다고 판단했다.
// submit 되면 실행되는 함수.
const onValid = (data: AuthFormValues) => {
handleSubmitForm(data);
};
인자에 대한 타입은 다음과 같다.
export interface LogInFormValues {
이메일: string;
비밀번호: string;
}
export interface SignUpFormValues extends LogInFormValues {
비밀번호확인: string;
닉네임: string;
주소: string;
상세주소: string;
우편번호: string;
전화번호: string;
이름: string;
}
export type AuthFormValues = LogInFormValues | SignUpFormValues;
인자로 들어오는 양식이 유니온 타입이기 때문에 실제로 API 요청을 할 때 어떤 타입으로 보낼지 타입을 좁힐 필요가 있었다.
🎉 해결
폼을 전송하는 함수를 가진 상위 컴포넌트에서 type predicates을 통해 react query의 mutate 함수로 전달하는 데이터의 타입을 좁혔다(type narrowing).
const isSignUp = (form: AuthFormValues): form is SignUpFormValues =>
'비밀번호확인' in form;
비밀번호확인 필드를 가지고 있으면 SignUpFormValues 타입이라는 뜻이 된다.
const handleSignUp = (data: AuthFormValues) => {
if (isSignUp(data)) mutate(data);
};
isSignUp 함수를 통과하고 나온 데이터는 무조건 SignUpFormValues 타입이다.