LoginPage.jsx
import "./LoginPage.css";
const LoginPage = () => {
return (
<section className="align_center form_page">
<form className="authentication_form">
<h2>로그인 폼</h2>
<div className="form_inputs">
<div>
<label htmlFor="email">Email</label>
<input
type="email"
id="email"
className="form_text_input"
placeholder="이메일 입력..."
/>
</div>
<div>
<label htmlFor="password">Password</label>
<input
type="password"
id="password"
className="form_text_input"
placeholder="패스워드"
/>
</div>
<button type="submit" className="search_button form_submit">
Submit
</button>
</div>
</form>
</section>
);
};
export default LoginPage;
LoginPage.css
.form_page {
justify-content: center;
}
.authentication_form {
width: 30%;
padding: 32px 48px;
margin-top: 32px;
background-color: #fff;
}
.authentication_form h2 {
font-size: 40px;
margin-bottom: 30px;
text-align: center;
}
.form_inputs div {
display: flex;
flex-direction: column;
margin-bottom: 20px;
}
.form_inputs label {
font-size: 18px;
font-weight: 600;
margin-bottom: 3px;
}
.form_text_input {
height: 35px;
padding: 0 8px;
font-size: 17px;
font-weight: 500;
outline: none;
}
.form_submit {
height: 40px;
width: 100%;
margin: 25px 0 10px;
}
.form_error {
color: red;
}
JavaScript 를 사용 할 때에는, 우리가 특정 DOM 을 선택해야 하는 상황에 getElementById, querySelector 같은 DOM Selector 함수를 사용해서 DOM 을 선택합니다.
리액트를 사용하는 프로젝트에서도 가끔씩 DOM 을 직접 선택해야 하는 상황이 발생 할 때도 있습니다.
그럴 땐, 리액트에서 ref 라는 것을 사용합니다.
함수형 컴포넌트에서 ref 를 사용 할 때에는 useRef 라는 Hook 함수를 사용합니다.
그래서 useRef를 사용해서 password input창을 선택하여 <비밀번호 보이게>를 클릭하면
입력한 비밀번호가 보이게 해줄거고, 숨기기를 클릭하면 ***와같이 안보이게 하도록 하겠다.
LoginPage.jsx
import { useRef } from "react";
import "./LoginPage.css";
const LoginPage = () => {
const passwordRef = useRef(null);
return (
<section className="align_center form_page">
<form className="authentication_form">
<h2>로그인 폼</h2>
<div className="form_inputs">
<div>
<label htmlFor="email">Email</label>
<input
type="email"
id="email"
className="form_text_input"
placeholder="이메일 입력..."
/>
</div>
<div>
<label htmlFor="password">Password</label>
<input
type="password"
ref={passwordRef}
id="password"
className="form_text_input"
placeholder="패스워드 입력..."
/>
<button
type="button"
onClick={() => console.log(passwordRef.current)}
>
비밀번호 숨기기
</button>
<button type="button">비밀번호 보이게</button>
</div>
<button type="submit" className="search_button form_submit">
Submit
</button>
</div>
</form>
</section>
);
};
export default LoginPage;
console.log로 찍어보면 아래와 같이 나온다.
import { useRef } from "react";
import "./LoginPage.css";
const LoginPage = () => {
const passwordRef = useRef(null);
return (
<section className="align_center form_page">
<form className="authentication_form">
<h2>로그인 폼</h2>
<div className="form_inputs">
<div>
<label htmlFor="email">Email</label>
<input
type="email"
id="email"
className="form_text_input"
placeholder="이메일 입력..."
/>
</div>
<div>
<label htmlFor="password">Password</label>
<input
type="password"
ref={passwordRef}
id="password"
className="form_text_input"
placeholder="패스워드 입력..."
/>
<button
type="button"
onClick={() =>
console.log((passwordRef.current.type = "password"))
}
>
비밀번호 숨기기
</button>
<button
type="button"
onClick={() => (passwordRef.current.type = "text")}
>
비밀번호 보이게
</button>
</div>
<button type="submit" className="search_button form_submit">
Submit
</button>
</div>
</form>
</section>
);
};
export default LoginPage;
비밀번호 숨기기를 클릭하면
input의 type을 password로
보이게를 클릭하면
input의 type을 text로 해서 보이도록 추가한다
1. 비밀번호 보이게 클릭
2. 비밀번호 숨기기 클릭
Usestate로 user의 email과 password를 관리한다.
const LoginPage = () => {
const [user, setUser] = useState({
email: "",
password: "",
});
const passwordRef = useRef(null);
//로그인 클릭 시 실행
const handleSubmit = (e) => {
e.preventDefault();
console.log(user);
};
<form onSubmit={handleSubmit} className="authentication_form">
<h2>로그인 폼</h2>
<div className="form_inputs">
<div>
<label htmlFor="email">Email</label>
<input
onChange={(e) => setUser({ ...user, email: e.target.value })}
type="email"
id="email"
className="form_text_input"
placeholder="이메일 입력..."
/>
</div>
<div>
<label htmlFor="password">Password</label>
<input
onChange={(e) => setUser({ ...user, password: e.target.value })}
type="password"
ref={passwordRef}
id="password"
className="form_text_input"
placeholder="패스워드 입력..."
/>
<button
type="button"
onClick={() => (passwordRef.current.type = "password")}
>
비밀번호 숨기기
</button>
<button
type="button"
onClick={() => (passwordRef.current.type = "text")}
>
비밀번호 보이게
</button>
</div>
<button type="submit" className="search_button form_submit">
Submit
</button>
</div>
</form>
onChange 로 이메일과 패스워드의 값이 바뀔때마다 setUser에 저장한다.
그리고 submit 시
handleSubmit 함수가 실행되면서 user를 출력한다.
//로그인 클릭 시 실행
const handleSubmit = (e) => {
e.preventDefault();
//console.log(user);
setUser({ email: "", password: "" });
};
submit 시 input창 초기화
<input
onChange={(e) => setUser({ ...user, email: e.target.value })}
value={user.email}
type="email"
id="email"
className="form_text_input"
placeholder="이메일 입력..."
/>
</div>
<div>
<label htmlFor="password">Password</label>
<input
onChange={(e) => setUser({ ...user, password: e.target.value })}
type="password"
value={user.password}
ref={passwordRef}
id="password"
className="form_text_input"
placeholder="패스워드 입력..."
/>
초기화 된 값 반영되게 value 추가
https://www.npmjs.com/package/react-hook-form
Form을 사용할 때 좀 더 편리하게 사용하기 위해서
react-hook-form 을 설치한다.
QuickStart 와 같이 작성해줄건데
일단
const { register, handleSubmit } = useForm();
const submitData = (formData) => console.log(formData);
<form onSubmit={handleSubmit(submitData)} className="authentication_form">
<h2>로그인 폼</h2>
<div className="form_inputs">
<div>
<label htmlFor="email">Email</label>
<input
{...register("email")}
// onChange={(e) => setUser({ ...user, email: e.target.value })}
//value={user.email}
type="email"
id="email"
className="form_text_input"
placeholder="이메일 입력..."
/>
</div>
<div>
<label htmlFor="password">Password</label>
<input
{...register("password")}
useRef()를 사용하면 password가 출력되지 않음 ㅠ 그래서
비밀번호 보이기 / 숨김 버튼은 일단 주석처리
해당 라이브러리를 사용하면 유효성 검사도 할 수 있다.
//react-hook-form 사용
const {
register,
handleSubmit,
formState: { errors },
} = useForm();
input에 검증이 필요한 속성을 입력
- required
- min (최소값)
- max (최대값)
- minLength (최소길이)
- maxLength
- pattern
- validate
input에 유효성 검사를 추가한다.
<h2>로그인 폼</h2>
<div className="form_inputs">
<div>
<label htmlFor="email">Email</label>
<input
{...register("email", { required: "이메일을 입력해주세요." })}
// onChange={(e) => setUser({ ...user, email: e.target.value })}
//value={user.email}
type="email"
id="email"
className="form_text_input"
placeholder="이메일 입력..."
/>
{errors.email && (
<em className="form_error">{errors.email.message}</em>
)}
</div>
<div>
<label htmlFor="password">Password</label>
<input
{...register("password", {
required: "패스워드를 입력해주세요.",
minLength: { value: 4, message: "패스워드는 최소 4자 이상." },
})}
// onChange={(e) => setUser({ ...user, password: e.target.value })}
// value={user.password}
type="password"
//ref={passwordRef}
id="password"
className="form_text_input"
placeholder="패스워드 입력..."
/>
{errors.password && (
<em className="form_error">{errors.password.message}</em>
)}