https://www.npmjs.com/package/react-hook-form
https://ko.legacy.reactjs.org/docs/forms.html#controlled-components
react hook form 이란?
react hook form 는 유효성 검사를 쉽게 할 수 있는 form을 제공하는 라이브러리이다.
react hook form 을 사용하는 이유?
1. 성능
Formik이나 Redux Form보다 속도가 훨씬 빠르다
https://github.com/react-hook-form/performance-compare
2. 소스코드가 깔끔
3. 비제어 컴포넌트 방식의 사용으로 불필요한 렌더링을 막아주어 속도가 빠르다.
제어 컴포넌트 vs 비제어 컴포넌트
제어 컴포넌트
HTML에서 <input>, <textarea>, <select>와 같은 폼 엘리먼트는 일반적으로 사용자의 입력을 기반으로 자신의 state를 관리하고 업데이트합니다. React에서는 변경할 수 있는 state가 일반적으로 컴포넌트의 state 속성에 유지되며 setState()에 의해 업데이트됩니다.
우리는 React state를 “신뢰 가능한 단일 출처 (single source of truth)“로 만들어 두 요소를 결합할 수 있습니다. 그러면 폼을 렌더링하는 React 컴포넌트는 폼에 발생하는 사용자 입력값을 제어합니다. 이러한 방식으로 React에 의해 값이 제어되는 입력 폼 엘리먼트를 “제어 컴포넌트 (controlled component)“라고 합니다.
출처 -https://ko.legacy.reactjs.org/docs/forms.html#controlled-components
function ControlledComponent() {
const [inputValue, setInputValue] = useState('');
const handleChange = (e) => {
setInputValue(e.target.value);
};
return (
<input type="text" value={inputValue} onChange={handleChange} />
);
}
제어 컴포넌트는 React 컴포넌트의 **상태(state)**가 입력 필드의 값(value)을 관리하는 방식이다.
입력 필드의 값은 항상 React 상태에 의해 "제어"된다.
- 상태로 값 관리: 사용자가 입력 필드에 무언가를 입력하면, onChange 이벤트가 발생하고 이를 통해 상태가 업데이트됩니다.
- 실시간 값 반영: 상태가 업데이트되면 즉시 입력 필드의 값이 변경됩니다
이러한 방식으로 데이터를 전부 받아올 수 있어 유효성 검사에 탁월한데
데이터를 하나하나 다 받아오므로 비효율적이거나 속도가 느릴 수 있는 단점이 있다
비제어 컴포넌트
대부분 경우에 폼을 구현하는데 제어 컴포넌트를 사용하는 것이 좋습니다. 제어 컴포넌트에서 폼 데이터는 React 컴포넌트에서 다루어집니다. 대안인 비제어 컴포넌트는 DOM 자체에서 폼 데이터가 다루어집니다.
모든 state 업데이트에 대한 이벤트 핸들러를 작성하는 대신 비제어 컴포넌트를 만들려면 ref를 사용하여 DOM에서 폼 값을 가져올 수 있습니다.
출처 - https://ko.legacy.reactjs.org/docs/uncontrolled-components.html
비제어 컴포넌트는 입력 필드의 값이 React 상태가 아닌 DOM 자체에서 관리되는 방식입니다. 즉, 입력 필드의 값은 React 상태와 독립적으로 관리된다.
특징:
- 참조로 값 관리: React에서는 ref를 사용해 직접 DOM에 접근하고, 입력 필드의 값을 참조할 수 있습니다.
- 값을 참조할 때만: 입력 필드의 값을 확인하거나 변경할 때만 DOM에 접근합니다.
ref는 값을 업데이트 하여도 리랜더링 되지 않는 특성으로, 입력이 모두 되고난 후 ref를 통해 값을 한번에 가져와서 활용한다.
function UncontrolledComponent() {
const inputRef = useRef(null);
const handleSubmit = (e) => {
e.preventDefault();
console.log(inputRef.current.value); // DOM에서 직접 값 접근
};
return (
<form onSubmit={handleSubmit}>
<input type="text" ref={inputRef} />
<button type="submit">Submit</button>
</form>
);
}
react-hook-form 시작하기
npm install react-hook-form
react-hook-form 주요개념
1. useForm
useForm은 React Hook Form의 핵심 함수로, 폼의 인스턴스를 생성하고 폼 데이터와 메서드를 제공한다.
2. register
register는 입력 필드를 react- hook-form에 등록하는 함수이다.
이를 통해 해당 입력필드의 값이 폼에 연결되고, 값을 쉽게 추적가능하다.
register에 옵션을 추가하여 검증(validation) 규칙을 설정할 수 있다.
import { useForm } from "react-hook-form";
function MyForm() {
const { register, handleSubmit } = useForm();
const onSubmit = (data) => {
console.log(data); // 입력 데이터 출력
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register("name")} /> {/* 'name' 필드를 등록 */}
<input {...register("age")} />
<button type="submit">Submit</button>
</form>
);
}
3.handleSubmit
handleSubmit은 폼 제출을 처리하는 함수이다.
폼이 제출될 때 입력된 데이터가 검정되며,유효한 경우에만 콜백 함수가 호출된다.
<form onSubmit={handleSubmit(onSubmit)}>
{/* 폼 제출 시 onSubmit 함수가 호출됨 */}
</form>
4.errors
errors는 폼 검증 중 발생한 에러를 추하고, 어떤 입력 필드에서 에러가 발생했는지를 보여준다.
이를 사용하여 각 입력 필드에 대해 발생한 에러를 errors를 통해 확인하고 에러 메시지 처리가 가능하다.
function MyForm() {
const { register, handleSubmit, formState: { errors } } = useForm();
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register("name", { required: true })} />
{errors.name && <p>Name is required</p>}
<button type="submit">Submit</button>
</form>
);
}
5.formState
formState는 폼의 상태를 추적하는 객체로, 폼이 현재 유효한지 변경되었는지, 제출 시도 여부 등을 추적할 수 있다.
- isValid : 폼이 유효한지 여부
- isDirty : 하나 이상의 입력 필드 값이 변경되었는지 여부
- isSubmitting : 폼이 제출 중인지 여부.
const { register, handleSubmit, formState: { isValid, isDirty } } = useForm();
6.reset
reset은 폼의 값을 초기화하는 함수이다.
이를 사용하면 제출 후 폼을 비우거나 특정 상태로 리셋 가능하다.
const { register, handleSubmit, reset } = useForm();
const onSubmit = (data) => {
console.log(data);
reset(); // 폼 초기화
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register("name")} />
<button type="submit">Submit</button>
</form>
);
7.watch
watch는 특정 입력 필드의 값을 실시간으로 추적할 수 있는 함수이다.
입력 필드의 변경 사항을 바로 갑지하고, 상태에 따라 동적인 UI를 제공할 수 있다.
const { register, watch } = useForm();
const nameValue = watch("name"); // 'name' 필드의 실시간 값 추적
8. setValue / getValues
- setValue : 입력 필드의 값을 변경할 때 사용한다.
-getValues : 현재 폼에 있는 입력 필드의 값을 가져오는 함수이다.
const { setValue, getValues } = useForm();
setValue("name", "John Doe"); // 'name' 필드의 값을 'John Doe'로 설정
console.log(getValues("name")); // 'name' 필드의 현재 값을 출력
9. useFormContext
useFormContext는 react-hook-form 의 컨텍스트 API를 사용하여 중첩된 컴포넌트에서 폼 상태를 쉽게 공유할 수 있도록한다. 여러 컴포넌트에서 폼 데이터를 관리할 때 유용하다.
import { useFormContext } from "react-hook-form";
function NestedComponent() {
const { register } = useFormContext();
return <input {...register("nestedField")} />;
}
10. Controller
Controller 는 제어 컴포넌트를 사용할 때 react-hook-form과 통합할 수 있는 방법을 제공한다.
제어 컴포넌트는 자체적으로 상태를 관리하는 컴포넌트로 일반적으로는 register 로 연결되지 않기 때문에
Controller 를 통해 폼 상태와 연결할 수 있다.
react-select / Meterial-UI / Ant Design 등 외부 라이브러리 컴포넌트는 자체 상태 관리 로직을 가지기 때문에
이를 react-hook-form 과 연결하려면 Controller 가 필요하다.
import { Controller, useForm } from "react-hook-form";
import Select from "react-select"; // 제어 컴포넌트
function MyForm() {
const { control, handleSubmit } = useForm();
return (
<form onSubmit={handleSubmit(onSubmit)}>
<Controller
name="select"
control={control}
render={({ field }) => <Select {...field} options={[{ value: '1', label: 'One' }]} />}
/>
<button type="submit">Submit</button>
</form>
);
}
react-select와 Controller 사용 예시
import React from 'react';
import { useForm, Controller, SubmitHandler } from 'react-hook-form';
import Select from 'react-select'; // 제어 컴포넌트인 react-select
// 폼 데이터 타입 정의
interface IFormInput {
favoriteColor: { value: string; label: string };
}
const options = [
{ value: 'red', label: 'Red' },
{ value: 'green', label: 'Green' },
{ value: 'blue', label: 'Blue' }
];
function MyForm() {
const { handleSubmit, control } = useForm<IFormInput>();
const onSubmit: SubmitHandler<IFormInput> = (data) => {
console.log(data); // 선택한 값 출력
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<label htmlFor="color">Favorite Color:</label>
{/* Controller로 react-select를 사용하여 폼과 연결 */}
<Controller
name="favoriteColor"
control={control}
render={({ field }) => (
<Select
{...field}
options={options}
placeholder="Select a color"
/>
)}
/>
<button type="submit">Submit</button>
</form>
);
}
export default MyForm;
-> control : useForm에서 가져오는 control은 폼 상태를 관리하는 객체이다. 이를 Controller와 함께 사용하여
폼 상태와 제어 컴포넌트를 연결할 수 있다.
-> Controller : name 속성을 통해 폼의 입력 필드 이름을 설정하고, control을 통해 상태를 관리한다.
rednter 함수는 제어 컴포넌트를 렌더링 하는 역할을 하며 field 라는 객체를 받아 해당 컴포넌트에 전달한다.
field 는 폼 상태와 이벤트( onChange, onBlur, value)를 관리하는 속성들을 포함한다.
기본 값 설정 : Controller 는 defaultValue를 통해 초기 값을 설정할 수 있음
검증 : rules 옵션을 사용하여 검증 규칙 추가 가능
<Controller
name="favoriteColor"
control={control}
defaultValue={options[0]} // 기본 값을 'Red'로 설정
rules={{ required: 'Please select a color' }} // 필수 입력 검증
render={({ field, fieldState }) => (
<>
<Select
{...field}
options={options}
placeholder="Select a color"
/>
{fieldState.error && <p>{fieldState.error.message}</p>}
</>
)}
/>
https://beomy.github.io/tech/react/react-hook-form/
/@yesoryeseul/react-hook-form-%EC%95%8C%EA%B3%A0-%EC%93%B0%EC%9E%90
'STUDY' 카테고리의 다른 글
[라이브러리] react-spring 애니메이션 구현 (1) | 2024.09.29 |
---|---|
<E2E 테스트> playwright E2E 테스트 및 깃허브 CI 설정하기 (1) | 2024.09.14 |
[react-signature-canvas] 전자서명 구현하기 (1) | 2024.09.13 |
axios 인스턴스 (0) | 2024.09.10 |
session 방식의 개념 및 한계와 JWT token 인증 방식 (0) | 2024.09.04 |