함수형 컴포넌트내 최상위 영역에서 hook을 호출해야 한다.
custom hook 내부에서 hook을 호출해야한다.
use
를 prefix로 갖도록 한다. 관리해야하는 상태관리가 늘어나는 만큼 handler, validation function 선언도 늘어난다.
관련하여 에러 메시지도 추가 될 것이다.
마지막으로 submit function의 로직이 복잡하고 비대해질 것으로 예상된다.
react-hook-form은 위에서 언급한 고민에 대한 해결책을 제공한다.
React Hook Form을 설치하는 것은 단 하나의 명령어만 있으면 된다.
npm install react-hook-form
다음 코드 발췌는 기본 사용 예를 보여준다.
import { useForm } from "react-hook-form";
export default function App() {
const { register, handleSubmit, watch, formState: { errors } } = useForm();
const onSubmit = data => console.log(data);
console.log(watch("example")); // watch input value by passing the name of it
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input defaultValue="test" {...register("example")} />
<input {...register("exampleRequired", { required: true })} />
{errors.exampleRequired && <span>This field is required</span>}
<input type="submit" />
</form>
);
}
React Hook Form의 핵심 개념 중 하나는 구성 요소를 후크에 연결하는 것이다. 이렇게 하면 양식 유효성 검사 및 제출 모두에 해당 값을 사용할 수 있다.
각 필드는 등록 프로세스를 위한 키로 있어야 한다.
name
import { useForm } from "react-hook-form";
export default function App() {
const { register, handleSubmit } = useForm();
const onSubmit = data => console.log(data);
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register("firstName")} />
<select {...register("gender")}>
<option value="female">female</option>
<option value="male">male</option>
<option value="other">other</option>
</select>
<input type="submit" />
</form>
);
}
React Hook Form은 양식 유효성 검사를 위한 기존 HTML 표준과 정렬하여 양식 유효성 검사를 쉽게 만든다.
import { useForm } from "react-hook-form";
export default function App() {
const { register, handleSubmit } = useForm();
const onSubmit = data => console.log(data);
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register("firstName", { required: true, maxLength: 20 })} />
<input {...register("lastName", { pattern: /^[A-Za-z]+$/i })} />
<input type="number" {...register("age", { min: 18, max: 99 })} />
<input type="submit" />
</form>
);
}
React Hook Form은 양식 errors
의 오류를 표시하는 개체를 제공한다. errors 유형은 주어진 유효성 검사 제약 조건을 반환한다.
다음 예는 필수 유효성 검사 규칙을 보여준다.
import { useForm } from "react-hook-form";
export default function App() {
const { register, formState: { errors }, handleSubmit } = useForm();
const onSubmit = (data) => console.log(data);
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input
{...register("firstName", { required: true })}
aria-invalid={errors.firstName ? "true" : "false"}
/>
{errors.firstName?.type === 'required' && <p role="alert">First name is required</p>}
<input
{...register("mail", { required: "Email Address is required" })}
aria-invalid={errors.mail ? "true" : "false"}
/>
{errors.mail && <p role="alert">{errors.mail?.message}</p>}
<input type="submit" />
</form>
);
}
import React , {useRef} from "react";
import { useForm } from "react-hook-form";
import "./styles.css";
function App() {
const { register, handleSubmit ,watch, formState : {errors}} = useForm();
console.log(watch("email"));
const password = useRef();
password.current = watch('password');
const onSubmit = data => {
console.log(data);
// axios.post('/',data) ...
}
return (
<form onSubmit={handleSubmit(onSubmit)}>
<label>Email</label>
<input
//name="email"
type="email"
{...register("email", { required: true, pattern: /^\S+@+\S+$/i })}
/>
{errors.email && <p>This email field is required</p>}
<label>Name</label>
<input
{...register('name', { required: true, maxLength : 10})}
/>
{errors.name && errors.name.type === 'required'&& <p>This field is required</p>}
{errors.name && errors.name.type === 'maxLength' && <p>Your input exceed maxium length</p>}
<label>Password</label>
<input
type="password"
{...register("password", { required: true , minLength:6})}
/>
{errors.password && errors.password.type === 'required' && <p>This field is required</p>}
{errors.password && errors.password.type === 'minLength' && <p>Your input exceed minium length</p>}
<label>Password Confirm</label>
<input
type="password"
{...register("password_confirm", { required: true, validate : (value) => value === password.current})}
/>
{errors.password_confirm && errors.password_confirm.type === 'required' && <p>This field is required</p>}
{errors.password_confirm && errors.password_confirm.type === 'validate' && <p>The passwords do not match</p>}
<input type="submit" />
</form>
);
}
export default App;
resister()의 값으로 value를 넣어주기 때문에 name 속성이 꼭 필요한게 아니라면, name 속성을 입력하지 않고 {...register('email')}로 제어가 가능하다.
name 속성의 값과 상관없이 watch() 안에 들어오는 value는 register()의 value이다.
errors는 useForm()을 구조분해해서 바로 꺼내오는 것이 아니라,
const {register, formState(errors)} = useForm() 처럼 선언해야 한다.
useRef를 이용해서 Password
와 Password Comfirm
이 같은지 비교할려면 아래와 같다.
- ref 생성
- watch를 이용하여 password 필드 값 가져오기
- 가져온 password 값을 ref.current에 넣어주기