보통 입력창의 집합
label
이랑 같이 쓰임
- 양식 제출 관리 ,입력한 값 추출
- 사용자 제공 데이터 검증하는 작업
export default function Login() {
return (
<form>
<h2>Login</h2>
<div className="control-row">
<div className="control no-margin">
<label htmlFor="email">Email</label>
<input id="email" type="email" name="email" />
</div>
<div className="control no-margin">
<label htmlFor="password">Password</label>
<input id="password" type="password" name="password" />
</div>
</div>
<p className="form-actions">
<button className="button button-flat">Reset</button>
<button className="button">Login</button>
</p>
</form>
);
}
htmlFor
: label을 클릭하면 시각적으로 라벨을 클릭하면 연결된 입력 요소가 활성화
-> 페이지가 새로고침됨
첫번째 방법
button type지정
<button type="button" className="button" onClick={handleSubmit}>
두번째 방법
type 지정 x form에 submit 이벤트
event.preventDefault();
이벤트 동작을 취소하는 메서드 페이지 로드 방지
<form onSubmit={handleSubmit}>
export default function Login() {
function handleSubmit(event) {
event.preventDefault();
}
ex)
//초기값
const [enteredValues, setEnteredValue] = useState({
email: "",
password: "",
});
function handleInputChange(identifier, value) {
setEnteredEmail((prev) => ({ ...prev, [identifier]: value }));
}
onChange={(event) => handleInputChange("email", event.target.value)}
[identifier]는 배열이 아니라, 객체의 속성(key)을 동적으로 설정하는 JavaScript의 문법 객체의 속성에 접근할 때 동적으로 속성을 지정하려면 대괄호 표기법([])을 사용
state통한 관리(Login)
import { useState } from 'react';
export default function Login() {
// const [enteredEmail, setEnteredEmail] = useState('');
// const [enteredPassword, setEnteredPassword] = useState('');
const [enteredValues, setEnteredValues] = useState({
email: '',
password: '',
});
function handleSubmit(event) {
event.preventDefault();
console.log(enteredValues);
}
function handleInputChange(identifier, value) {
setEnteredValues((prevValues) => ({
...prevValues,
[identifier]: value,
}));
}
// function handleEmailChange(event) {
// setEnteredEmail(event.target.value);
// }
// function handlePasswordChange(event) {
// setEnteredPassword(event.target.value);
// }
return (
<form onSubmit={handleSubmit}>
<h2>Login</h2>
<div className="control-row">
<div className="control no-margin">
<label htmlFor="email">Email</label>
<input
id="email"
type="email"
name="email"
onChange={(event) => handleInputChange('email', event.target.value)}
value={enteredValues.email}
/>
</div>
<div className="control no-margin">
<label htmlFor="password">Password</label>
<input
id="password"
type="password"
name="password"
onChange={(event) =>
handleInputChange('password', event.target.value)
}
value={enteredValues.password}
/>
</div>
</div>
<p className="form-actions">
<button className="button button-flat">Reset</button>
<button className="button">Login</button>
</p>
</form>
);
}
참조를 만들어서 참조 속성과 연결해서 값을 추출하기만 하면됨 current가 실제 연결된 값을 갖고 있음
- 복잡한 로직이면 많은 참조를 만들어서 하나하나 연결해야돼서 번거로울 수 있음
const enteredEmail = email.current.value; <input id="email" type="email" name="email" ref={email} />
useRef통한 관리
import { useRef } from "react";
export default function Login() {
const email = useRef();
const password = useRef();
function handleSubmit(event) {
event.preventDefault();
//current가 실제 연결된 값을 갖고있음
const enteredEmail = email.current.value;
const enteredPassword = password.current.value;
console.log(enteredEmail, enteredPassword);
}
return (
<form onSubmit={handleSubmit}>
<h2>Login</h2>
<div className="control-row">
<div className="control no-margin">
<label htmlFor="email">Email</label>
<input id="email" type="email" name="email" ref={email} />
</div>
<div className="control no-margin">
<label htmlFor="password">Password</label>
<input id="password" type="password" name="password" ref={password} />
</div>
</div>
<p className="form-actions">
<button className="button button-flat">Reset</button>
<button className="button">Login</button>
</p>
</form>
);
}
브라우저 내장함수, 양식에 입력된 각기 다른 값들을 쉽게 얻을 수 있음
모든 입력창
에name
속성이 있어야한다.FormData
객체에서 불러낸Entry
메소드의 결과를fromEntries
객체로 보냄 -> 모든 입력창과 값들의 배열을 제공
export default function Signup() {
function handleSubmit(event) {
event.preventDefault();
const fd = new FormData(event.target);
const acquisitionChannel = fd.getAll("acquisition"); //같은 이름을 가진 값을 얻으려면(배열로 저장)
const data = Object.fromEntries(fd.entries());
data.aquisition = acquisitionChannel;
}
<button type="reset" className="button button-flat">
버튼 타입에 reset
주는 방법
event.target.reset();
초기값으로 만들기
const [enteredValues, setEnteredValue] = useState({
email: "",
password: "",
});
function handleSubmit(event) {
event.preventDefault();
setEnteredValues({
email:"",
password"",
})
}
직접 참조값을 초기화하는것은 위험
export default function Login() {
const email = useRef();
const password = useRef();
function handleSubmit(event) {
event.preventDefault();
//current가 실제 연결된 값을 갖고있음
const enteredEmail = email.current.value;
const enteredPassword = password.current.value;
console.log(enteredEmail, enteredPassword);
email.current.value = "";
}
Form에서
ref
나 빌트인Formdata
를 이용했을때는 매 키 입력이 아닌 Form이 제출된 후에 데이터를 얻음 따라서State
접근법을때 사용
const [didEdit, setDidEdit] = useState({
email: false,
password: false,
});
function handleInputBlur(identifier) {
setDidEdit((prevEdit) => ({
...prevEdit,
[identifier]: true,
}));
}
<input
id="email"
type="email"
name="email"
onBlur={() => handleInputBlur("email")}
onChange={(event) => handleInputChange("email", event.target.value)}
value={enteredValues.email}
/>
type에 맞춰서 required가 적용됨
<input
id="password"
type="password"
name="password"
required
minLength={4} //최소 4글자
/>