STUDY

[라이브러리] react hook form 유효성 검사하는 폼 만들기

죠으닝 2024. 9. 18. 12:26

 

 

 

https://www.npmjs.com/package/react-hook-form

 

react-hook-form

Performant, flexible and extensible forms library for React Hooks. Latest version: 7.53.0, last published: 19 days ago. Start using react-hook-form in your project by running `npm i react-hook-form`. There are 5111 other projects in the npm registry using

www.npmjs.com

 

 

https://ko.legacy.reactjs.org/docs/forms.html#controlled-components

 

폼 – React

A JavaScript library for building user interfaces

ko.legacy.reactjs.org

 


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/

 

[React] react-hook-form으로 폼 관리하기

React Hook Form은 사용자 입력을 받고 검증하는 것을 도와 주는 라이브러리로, React에서 폼을 관리하는 가장 유명한 라이브러리 중 하나입니다. React Hook Form을 사용하면 사용자에게 입력을 받고 검

beomy.github.io

 

https://velog.

/@yesoryeseul/react-hook-form-%EC%95%8C%EA%B3%A0-%EC%93%B0%EC%9E%90

 

react-hook-form 알고 쓰자

➡️ 먼저 react-hook-form이란 무엇인가? > Performant, flexible and extensible forms with easy-to-use validation. 유효성 검사를 쉽게 할 수 있는, 성능이 우수하고 유연하며 확장 가능한 form을 제

velog.io