⭐️
input
속성값 및 value를 얻기위해e
값을 많이 쓸텐데, 해당e
의 속성 타입은 다음과 같이 지정해주면 된다.
const onInputChange = (e:React.ChangeEvent<HTMLInputElement>) => { ... }
⭐️
submit
함수에서,e
의 속성 타입은 다음과 같이 지정해주면 된다.
const onSubmit = (e:React.FormEvent<HTMLFormElement>) => { ... }
// ✅내코드
// input값 검증을 위한 type을 지정 : React.ChangeEvent<HTMLInputElement>를 적용해주어야 한다.
const onCheckValidationEmail = (e: React.ChangeEvent<HTMLInputElement>) => {
setEmail(e.target.value);
};
const onCheckValidationPassword = (
e: React.ChangeEvent<HTMLInputElement>
) => {
setPassword(e.target.value);
};
const onCheckValidationPasswordConfirm = (
e: React.ChangeEvent<HTMLInputElement>
) => {
setPasswordConfirm(e.target.value);
};
이렇게 작성하면 각 input
마다 제각기 다른 onChange
함수를 넣어줘야 한다.
하지만 아래처럼 작성한다면? 하나의 함수로 유효성 검사가 가능하다.
const onInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const {
target: { name, value },
// 이렇게 객체 분해 할당으로 e의 target에 접근하여 input의 name 속성과 value에 접근가능
} = e;
// ⬆️ 응용하여 하나의 함수에서 input validation을 수행가능.
if (name === "email") {
setEmail(value);
const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
if (!value?.match(emailRegex)) {
setError("이메일 형식이 올바르지 않습니다.");
} else {
setError("");
}
}
if (name === "password") {
setPassword(value);
if (value?.length < 8) {
setError("비밀번호는 8자리 이상이어야 합니다.");
} else if (passwordConfirm?.length > 0 && value !== password) {
setError(
"비밀번호가 비밀번호 확인깂이 다릅니다. 다시 한 번 확인해주세요."
);
} else {
setError("");
}
}
if (name === "password__check") {
setPasswordConfirm(value);
if (password !== value) {
setError(
"비밀번호가 비밀번호 확인깂이 다릅니다. 다시 한 번 확인해주세요."
);
} else {
setError("");
}
}
};
return (
<form onSubmit={onSubmit} className="form form-lg">
<h1 className="form__title">회원가입</h1>
<div className="form_block">
<label htmlFor="email">이메일</label>
<input
type="email"
name="email"
id="email"
onChange={(e) => onInputChange(e)}
required
/>
</div>
<div className="form_block">
<label htmlFor="password">비밀번호</label>
<input
type="password"
name="password"
id="password"
onChange={(e) => onInputChange(e)}
required
/>
</div>
<div className="form_block">
<label htmlFor="password__check">비밀번호 확인</label>
<input
type="password"
name="password__check"
id="password__check"
onChange={(e) => onInputChange(e)}
required
/>
</div>
{error && error?.length > 0 && (
<div className="form__block">
<div className="form__error">{error}</div>
</div>
)}
<div className="form_block">
<b>이미 계정이 있으신가요?</b>
<Link to="/login" className="form__link">
로그인하기
</Link>
</div>
<div className="form_block">
<input
type="submit"
value="회원가입"
className="form_btn--submit login__btn"
disabled={error?.length > 0}
/>
</div>
</form>
);
};
신세계다..
const onInputChange = (e: React.ChangeEvent<HTMLInputElement>) => { const { target: { name, value }, } = e; ... }
객체 분해 할당으로 e의 target에 접근하여 input의 name 속성과 value에 접근가능
나는 지금껏 하나의 함수로 어떻게 해야 각 input의 유효성을 검사 및 검증할 수 있을까 생각해봤었는데, 막상 떠오르지 않았었다.
그러나 오늘을 기점으로 해당 방식처럼 깔끔하게 하나의 함수로 검증할 수 있게 되었다.
공식문서에 보면 다 나와있지만, 간결하게 정리하자면
1. 최상단 파일에 import
하여 적용시켜줘야함. css 파일도!!
import "./App.css";
import { useState } from "react";
import Router from "./components/Router";
import { app } from "firebaseApp";
import { getAuth } from "firebase/auth";
import { ToastContainer } from "react-toastify";
import "react-toastify/dist/ReactToastify.css";
function App() {
const auth = getAuth(app);
// !! 연산자로 쉽게 boolean값으로 추론할 수 있도록 해준다.
const [isAuth, setIsAuth] = useState<boolean>(!!auth?.currentUser);
return (
<>
<ToastContainer />
<Router auth={isAuth} />;
</>
);
}
export default App;
사용 예시
// toast UI를 사용하고자 하는 컴포넌트
import { toast } from "react-toastify";
...
// form 전송시에는 FormEvent
const onSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
try {
const auth = getAuth(app);
await createUserWithEmailAndPassword(auth, email, password);
toast.success("회원가입 완료!", { position: "top-right" });
setEmail("");
setPassword("");
setPasswordConfirm("");
navigate("/");
} catch (error: any) {
toast.error(error?.message, { position: "top-right" });
}
};
toast.success 및 toast.error에 첫 번째 인수 : 화면에 띄울 텍스트
두번째 인수 : toast UI를 표시할 위치
toast UI 적용 img