일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- grid-column-end
- javascipt
- grid-column-start
- className
- prompt()
- createElement
- foreach()
- var
- valuable
- classList
- python #qqplot #qq-plot #code
- variables
- react-hook-form
- gird-row-end
- confirm()
- javascript
- border-style
- grid-row-start
- CSS
- React
- mongodb
- package.json
- localStorage
- css#cascading#display#block#inline
- scope
- box-shadow
- relative
- collapsing-margins
- Grid
- grid-template-areas
- Today
- Total
data life
[React] React-Hook-Form에 대해 알아보기 본문
이번 프로젝트 로그인/회원가입 구현을 맡으면서 사용한 react-hook-form에 대해 정리해보려고 합니다.
react-hook-form은 form의 validation을 도와주는 라이브러리로 성능적으로도 더 뛰어나다고 합니다만 자세한 건 공식문서를 참고해보시는 걸로!!
📌 참고로
- 쓰면서 굉장히 유용했고 자주 이용했던 부분 위주로 설명할 예정입니다.
- 공식문서는 다크모드로 보시길 추천드립니다.
1. useForm
form을 만들기 위해서는 useForm을 이용해야합니다.
const { register } = useForm({
mode: 'onSubmit',
reValidateMode: 'onChange',
defaultValues: {},
resolver: undefined,
context: undefined,
criteriaMode: "firstError",
shouldFocusError: true,
shouldUnregister: false,
shouldUseNativeValidation: false,
delayError: undefined
})
- mode : 동작을 제출하기 전에 검증하는 방법 ⭐️
- reValidateMode : 동작을 제출한 후 검증하는 방법
- defaultValues : 초기값 설정 ⭐️
- resolver : 커스텀한 유효성 검사 로직 사용 가능
- context : 유효성 검사기(resolver)에 전달할 컨텍스트를 설정합니다. 일반적으로 유효성 검사기가 다른 데이터나 함수에 접근해야 할 때 사용됩니다.
- criteriaMode : 여러 개의 에러가 발생했을 때 어떤 에러를 우선하여 보여줄지를 설정
- shouldFocusError : 유효성 검사에 실패한 필드에 자동으로 포커스를 맞출지 여부를 설정합니다. true로 설정하면 실패한 필드에 포커스가 이동됩니다.
- shouldUnregister : 등록된 폼 필드를 언제 해제할지를 설정합니다. false로 설정하면 폼이 리셋되어도 등록된 필드는 유지됩니다.
- shouldUseNativeValidation : 브라우저 기본 유효성 검사를 사용할지 여부를 설정합니다. false로 설정하면 React Hook Form의 내장 유효성 검사를 사용합니다.
- delayError : 에러 메시지를 보여주는 딜레이를 설정합니다. 일정 시간이 지난 후에 에러 메시지를 보여주고자 할 때 사용됩니다.
mode / reValidateMode 옵션들
- onBlur 모드: 입력 필드가 포커스를 잃을 때 유효성 검사가 수행됩니다. 이는 유저에게 폼을 작성하는 도중에 계속적으로 오류 메시지가 나타나는 것을 방지하여 좋은 사용자 경험을 제공합니다. 특히 복잡하거나 긴 폼에서 유용
- onChange 모드: 사용자가 입력을 하는 즉시 유효성 검사가 수행됩니다. 이는 즉각적인 피드백을 제공하여, 간단한 폼에 유용할 수 있습니다.
- onSubmit 모드 : 사용자가 폼을 제출할 때만 유효성 검사가 수행됩니다. 사용자가 제출 버튼을 클릭하거나 폼을 제출할 때ㄲ까지 어떠한 간섭을 하지 않습니다.
다음은 onBlur모드를 이용한 로그인 화면입니다.
useForm을 도와주는 함수에 대해 알아보도록 합시다.
const {
register
unregister
formState
watch
handleSubmit
reset
resetField
setError
clearErrors
setValue
setFocus
getValues
getFieldState
trigger
control
} = useForm();
1. register
각각의 폼 입력 필드와 연결되어, 그 필드의 값들을 추적하고 관리하는데 사용됩니다.
const { register } = useForm();
<input {...register("firstName")} />
register 함수에 전달하는 문자열 인자는 해당 입력 필드의 이름입니다. 이름을 통해 폼의 다른 부분에서 해당 입력 필드의 값을 참조하고 변경할 수 있습니다.
register 함수를 통해 입력 필드에 더 많은 설정을 추가할 수 있습니다. 예를 들어, 필수 입력 필드를 설정하거나 유효성 검사 규칙을 추가할 수 있습니다. 만약 필드 값이 이러한 규칙을 위반하면 react-hook-form은 해당 필드의 에러 상태를 관리하고, 이를 사용하여 에러 메시지를 표시할 수 있습니다.
<input {...register("firstName", { required: true })} />
<input {...register("age", { min: 18, max: 99 })} />
<input
{...register('password', {
required: '비밀번호는 필수 입력입니다.',
pattern: {
value: /^(?=.*?[A-Za-z])(?=.*?[0-9]).{6,}$/,
message:
'영문, 숫자를 포함한 6자 이상의 비밀번호를 입력해주세요.',
},
})}
errors={errors}
/>
- required
- min/maxLength
- min/max
- pattern
- validate
등등..
이외는 공식문서 참조
2. unregister
3. formState
현재 폼 상태에 대한 여러 정보를 포함하고 있습니다.
formState 객체에는 여러 속성이 있습니다
- isDirty: 사용자가 어느 한 입력 필드를 수정했는지 여부를 나타냅니다.
- isValid: 현재 폼 값이 모든 유효성 검사 규칙을 통과했는지 여부를 나타냅니다.
- errors: 현재 폼의 각 필드에서 반환된 유효성 검사 오류입니다.
- isSubmitted: 폼이 이미 제출되었는지 여부를 나타냅니다.
- isSubmitting: 폼이 현재 제출 중인지 여부를 나타냅니다.
- isTouched: 사용자가 어느 한 입력 필드를 터치했는지 여부를 나타냅니다.
이러한 속성들은 폼의 현재 상태에 따라 UI를 업데이트하거나 특정 동작을 실행하는 데 유용합니다. 예를 들어, isValid 속성은 폼이 유효한 경우에만 제출 버튼을 활성화하는 데 사용할 수 있습니다.
const { formState: { isValid } } = useForm();
<button disabled={!isValid}>Submit</button>
또한 errors 속성을 사용하여 각 필드에 대한 오류 메시지를 표시할 수 있습니다.
const { register, formState: { errors } } = useForm();
<input {...register("firstName", { required: "필수 입력 값입니다." })} />
{errors.firstName && <p>{errors.firstName.message}</p>}
4. watch
입력 필드의 상태를 실시간으로 확인하는데 사용됩니다. watch는 모든 입력의 상태를 관찰하며, 필드의 변경 사항이 있을 때마다 새로운 값을 반환합니다.
❗️ watch는 입력 필드의 상태를 실시간으로 감시하므로, 복잡한 폼에서는 성능에 영향을 줄 수 있으니 주의해서 사용해야 합니다.
특정 필드 감시: watch 함수에 필드 이름을 인수로 전달하여 특정 필드를 감시할 수 있습니다.
const { register, watch } = useForm();
const firstName = watch("firstName");
모든 필드 감시: watch 함수에 인수를 전달하지 않으면 모든 필드를 감시합니다. 이 경우, watch는 입력 필드의 전체 상태 객체를 반환합니다.
const { register, watch } = useForm();
const allFields = watch();
여러 필드 감시: watch 함수에 필드 이름의 배열을 전달하여 여러 필드를 동시에 감시할 수 있습니다.
const { register, watch } = useForm();
const [firstName, lastName] = watch(["firstName", "lastName"]);
5. handleSubmit
폼의 제출 이벤트를 처리하는데 사용됩니다. 이 함수는 콜백 함수를 인수로 받으며, 폼이 유효한 경우에만 이 콜백 함수를 실행합니다.
콜백 함수는 폼 데이터를 인수로 받습니다. 폼 데이터는 입력 필드의 이름을 키로 가지고 있는 객체입니다.
handleSubmit 함수는 자동으로 event.preventDefault()를 호출하여 페이지의 자동 리프레시를 막고, 입력된 데이터를 수집한 후 유효성을 검사합니다. 유효성 검사를 통과하면, handleSubmit는 콜백 함수를 실행합니다.
export default function App() {
const { register, handleSubmit } = useForm();
const onSubmit = data => console.log(data);
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input name="firstName" ref={register} />
<input name="lastName" ref={register} />
<button type="submit">Submit</button>
</form>
);
}
또한, handleSubmit는 선택적으로 두 개의 콜백 함수를 더 받을 수 있습니다. 두 번째 콜백 함수는 유효성 검사에서 오류가 발생했을 때 실행되고, 세 번째 콜백 함수는 폼이 제출될 때 항상 실행됩니다.
handleSubmit(onSubmit, onError, onFinally);
- onSubmit : 유효성 검사를 통과했을 때 실행되는 콜백
- onError : 유효성 검사에서 오류가 발생했을 때 실행되는 콜백
- onFinally : 폼 제출 후 항상 실행되는 콜백
6. reset
폼의 입력 필드를 초기 상태로 되돌리는데 사용됩니다. 즉, 입력 값, 오류, 더티 필드, 터치된 필드 등의 상태가 모두 초기화 됩니다.
❗️ 그러나, useForm의 defaultValues를 변경하지 않습니다.
function MyForm() {
const { register, handleSubmit, reset } = useForm();
const onSubmit = data => {
console.log(data);
// submit 후 form reset
reset();
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register("firstName")} defaultValue="test" />
<input {...register("lastName")} />
<button type="submit">Submit</button>
</form>
);
}
7. setError
특정 입력 필드에 프로그래밍 방식으로 오류를 설정할 수 있습니다. 이는 서버에서 오류 메시지를 받아 폼에 적용하거나, 사용자 정의 유효성 검사기를 사용하여 오류를 설정할 때 유용합니다.
function MyForm() {
const { register, handleSubmit, setError } = useForm();
const onSubmit = data => {
if (/* some condition */) {
setError("firstName", {
type: "manual",
message: "First name is required"
});
}
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register("firstName")} />
<button type="submit">Submit</button>
</form>
);
}
첫 번째 인자는 오류를 설정할 필드의 이름입니다.
두 번째 인자는 오류 객체로, 이는 type과 message 속성을 포함할 수 있습니다.
- type : 오류의 유형을 나타내는 문자열
- message : 사용자에게 보여줄 오류 메시지
8. clearError
setError를 통해 설정된 특정 입력 필드의 오류 상태를 지울 수 있습니다.
9. setValue
폼의 특정 필드에 값을 설정하는데 사용됩니다. 이는 상태 관리 없이 직접적으로 입력 필드에 값을 설정할 수 있게 해줍니다.
- name: 값을 설정하려는 필드의 이름입니다.
- value: 설정하려는 값입니다.
- options: 추가적인 옵션 객체로 shouldValidate와 shouldDirty라는 선택적 프로퍼티를 포함하고 있습니다.
- shouldValidate는 설정 후 유효성 검사를 수행할지 여부를 설정하며,
- shouldDirty는 필드를 'dirty' 상태로 설정할지 여부를 결정합니다.
❓dirty 란?
주로 사용자가 어떤 형태로든 입력 필드에 대한 변경을 수행했을 때 사용되는 용어로, 이는 사용자의 상호작용이 발생했음을 나타내는 방법 중 하나입니다. 따라서, 폼의 특정 필드가 "dirty"라는 것은 해당 필드에 대한 사용자의 입력이 한 번 이상 발생했음을 의미합니다.
function MyForm() {
const { register, handleSubmit, setValue } = useForm();
const onSubmit = data => {
// 제출 로직
};
const changeValue = () => {
setValue("firstName", "new value", { shouldValidate: true, shouldDirty: true });
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register("firstName")} />
<button type="button" onClick={changeValue}>Change Value</button>
<button type="submit">Submit</button>
</form>
);
}
"firstName" 필드의 값을 "new value"로 설정하며, 이때 해당 필드는 유효성 검사를 수행하고 'dirty' 상태로 표시됩니다.
10. setFocus
특정 폼 필드에 포커스를 설정할 수 있습니다.
setFocus('fieldName');
지정된 필드 'fieldName' 에 포커스가 설정됩니다. 이것은 주로 사용자의 주의를 특정 필드로 유도하거나, 폼의 유효성 검사에서 오류가 발생했을 때 해당 필드로 사용자를 안내하는 데 유용합니다.
11. getValues
현재 폼 필드의 값들을 얻을 수 있습니다.
폼의 상태를 검사하거나 특정 작업을 수행하기 전에 현재의 폼 값들을 확인하는 데 getValues 함수가 유용하게 사용됩니다.
const [username, email] = getValues(['username', 'email']);
console.log(username, email);
12. getFieldState (v7 이상)
해당 필드의 상태 정보를 반환합니다. 폼의 특정 필드에 대한 상세한 상태 정보를 얻고 싶을 때 유용하게 사용됩니다. 특히 유효성 검사와 관련된 로직을 처리할 때 이 함수를 활용할 수 있습니다.
- isDirty: 사용자가 필드를 수정한 후라면 true, 그렇지 않다면 false.
- isTouched: 사용자가 필드를 클릭한 적이 있으면 true, 그렇지 않다면 false.
- isValid: 해당 필드가 유효성 검사를 통과하면 true, 그렇지 않다면 false.
- error: 해당 필드에 대한 에러 메시지가 있다면 그 메시지를, 그렇지 않다면 undefined.
13. trigger
주어진 필드나 필드들의 유효성을 검사합니다. 이 메서드는 useForm hook에서 반환되며, 이를 사용해 특정 필드 또는 전체 필드의 유효성 검사를 수동으로 실행할 수 있습니다.
function Form() {
const { register, trigger } = useForm();
return (
<form>
<input {...register("username", { required: true })} />
<button onClick={() => trigger("username")}>검사</button>
</form>
);
}
export default Form;
trigger 메서드를 사용해 유효성 검사를 실행하고, 그 결과에 따라 추가적인 로직을 실행할 수 있습니다.
14. control
Controller 컴포넌트에서 사용되며, 비제어 컴포넌트를 제어 컴포넌트처럼 동작하게 할 수 있도록 합니다.
이는 리액트의 기본적인 Form 동작에서 벗어나는 특수한 경우나, 외부 UI 라이브러리와 함께 사용할 때 유용합니다.
Controller 컴포넌트의 여러 props
- name: 컨트롤하는 필드의 이름(필수)
- control: useForm으로부터 반환된 control 객체(필수)
- rules: 유효성 검사 규칙
- defaultValue: 필드의 기본 값
- render: 필드를 렌더링하는 함수
Controller의 render prop은 필드를 렌더링하는 함수를 받습니다.
이 함수는 { field, fieldState, formState } 객체를 인자로 받습니다.
- field는 { onChange, onBlur, name, ref, value }와 같은 필드와 관련된 속성을 가지고 있습니다. 이는 <input />과 같은 입력 요소에 바인딩해 사용합니다.
- fieldState는 해당 필드의 상태 (error, isTouched 등)를 가지고 있습니다.
- formState는 전체 폼의 상태 (isDirty, isValid 등)를 가지고 있습니다.
이러한 속성들을 이용해 우리는 필드를 커스텀하게 렌더링할 수 있습니다.
import { useForm, Controller } from "react-hook-form";
function Form() {
const { handleSubmit, control } = useForm();
return (
<form onSubmit={handleSubmit(data => console.log(data))}>
<Controller
name="firstName"
control={control}
defaultValue=""
render={({ field }) => <input {...field} />}
/>
<Controller
name="lastName"
control={control}
defaultValue=""
render={({ field }) => <input {...field} />}
/>
<input type="submit" />
</form>
);
}
export default Form;
'Front-end > React' 카테고리의 다른 글
[React] React Google OAuth2 - 구글 소셜로그인 구현(1) (0) | 2023.08.23 |
---|---|
[React] React-Query 사용해보기(1) (0) | 2023.08.19 |
[React] 제어 / 비제어 컴포넌트 (0) | 2023.04.02 |
[React] 이벤트 처리 (0) | 2023.03.29 |
[React] List와 Key 개념 (0) | 2023.03.29 |