[React] React Hook Form

React에서 React Hook Form 사용 방법에 대해 알아보겠습니다.

기본적으로 Form을 사용할 때 작성하는 코드입니다. 하나의 input 이지만 여러 개의 input 을 사용할 경우 useStateonChange 이벤트가 많이 생성됩니다.
그리고 Validation Check 하는 코드도 복잡해집니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// InputForm.tsx
import React, { useState } from 'react';

function InputForm() {
const [toDo, setTodo] = useState('');
const [toDoError, setTodoError] = useState('');
const onChange = (event: React.FormEvent<HTMLInputElement>) => {
const {
currentTarget: { value },
} = event;
setTodoError('');
setTodo(value);
};
const onSubmit = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
if (toDo.length < 10) {
return setTodoError('To do should be longer');
}
console.log(toDo);
};

return (
<div>
<form onSubmit={onSubmit}>
<input onChange={onChange} value={toDo} placeholder="Write a to do" />
<button>추가</button>
{toDoError !== '' ? toDoError : null}
</form>
</div>
);
}

export default InputForm;

react-hook-form 라이브러리를 사용하면 위의 코드들을 간략하게 줄일 수 있습니다. 그리고 Validation(검증)도 쉽게 관리할 수 있습니다.

설치

1
$ npm install react-hook-form

또는 yarn을 사용한다면 이 명령어를 사용하면 됩니다.

1
$ yarn add react-hook-form

사용

먼저 useForm 을 import 합니다.

1
import { useForm } from 'react-hook-form';

register

useForm, register을 사용한 단 한줄의 코드가 onChange 이벤트와 value, useState 를 모두 대체했습니다.
사용법은 {...register(name)}를 input 태그 안에 작성합니다.

register 함수는 Validation을 보다 쉽게 관리할 수 있도록 해줍니다. required: true처럼 조건을 작성할 수 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// InputForm.tsx
function InputForm() {
const { register } = useForm();

return (
<div>
<form>
<input {...register('toDo', { required: true })} placeholder="Write a to do" />
<button>추가</button>
</form>
</div>
);
}

export default InputForm;

watch

watch는 form의 입력 값들의 변화를 관찰할 수 있게 해줍니다.

1
2
const { register, watch } = useForm();
console.log(watch);

handleSubmit

handleSubmit는 form 데이터의 Validation Check를 해결해 줍니다. 파라미터는 Validation을 통과했을 때 호출되는 함수입니다.

handleSubmit를 사용하면 키보드랑 마우스를 조건이 유효하지 않은 항목으로 바로 focus 시켜줍니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// InputForm.tsx
function InputForm() {
const { register, handleSubmit } = useForm();
const onValid = (data: any) => {
console.log(data);
};

return (
<div>
<form onSubmit={handleSubmit(onValid)}>
<input
{...register('toDo', {
required: true,
minLength: {
value: 5,
message: 'Your todo is too short.',
},
})}
placeholder="Write a to do"
/>
<button>추가</button>
</form>
</div>
);
}

export default InputForm;

formState

formState 을 통해 에러메시지를 출력해 보겠습니다.

먼저 email 은 정규식을 통해 검증하도록 pattern을 작성하였습니다. 조건을 입력할 때 메시지도 작성하여 에러메시지가 출력되도록 하였습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
type IForm = {
errors: {
email: {
message: string;
};
};
email: string;
};

function InputForm() {
const {
register,
handleSubmit,
formState: { errors },
} = useForm<IForm>({
defaultValues: {
email: '@gmail.com',
},
});
const onValid = (data: IForm) => {
console.log(data);
};

return (
<div>
<form onSubmit={handleSubmit(onValid)}>
<input
{...register('email', {
required: '이메일을 입력하세요.',
pattern: {
value: /^[A-Za-z0-9._%+-]+@gmail.com$/,
message: '이메일 형식이 맞지 않습니다.',
},
})}
placeholder="Email"
/>
<span>{errors?.email?.message}</span>
<button>등록</button>
</form>
</div>
);
}

export default InputForm;

email을 입력하지 않았을 경우 이메일을 입력하세요. 에러메시지가 출력되고 email 형식이 맞지 않을 경우 이메일 형식이 맞지 않습니다. 에러메시지가 출력됩니다.

SetValue

submit 하고 난 후 값을 초기화할 수 있습니다.

Custom Validation

  • setError 를 통해 직접 에러를 발생시키도록 할 수 있습니다.
  • shouldFocus 옵션을 사용하면 form의 커서가 자동으로 옮겨집니다.
1
2
// 예
setError('password1', { message: '비밀번호가 다릅니다.' }, { shouldFocus: true });

참고

공유하기