React Hook Form - register

2025. 8. 13. 14:50Coding Study/React

https://react-hook-form.com/

 

React Hook Form - performant, flexible and extensible form library

Performant, flexible and extensible forms with easy-to-use validation.

react-hook-form.com

 

 

설치

npm install react-hook-form

 

register

  useForm 에서 반환하는 속성에 register 라는 속성이 있다.

 

const { register } = useForm();

 

 

const { register } = useForm();

return (
  <form>
    <input
      type="file"
      id="image"
      {...register('image')}
    />
    <button type="submit">제출</button>
  </form>
);

 

register 함수는 이 필드 이름 'image'를 바탕으로 다음 속성들을 포함한 객체를 반환한다.

  • name: 'image'
  • onChange: ...
  • onBlur: ...
  • ref: ...

 

 

 

아래 예제를 보면 register 가 함수로 정의 되어 있다는 것을 알 수 있다.

  - createButtonProps를 함수로 정의 하고 return 값을 객체로 하면

  - 스프레드 + 함수이름 +( 인수 ) 로 정의해서 Props를 넘겨 줄 수 있다.

// Button.jsx
function Button({ label, onClick }) {
  return <button onClick={onClick}>{label}</button>;
}

// createButtonProps 함수는 버튼에 필요한 속성들을 객체로 반환합니다.
function createButtonProps(label, onClickHandler) {  
  return {
    label: label,
    onClick: onClickHandler
  };
}

// App.jsx
function App() {
  const handleClick = () => {
    alert('버튼이 클릭되었습니다!');
  };

  // createButtonProps 함수를 호출하여 반환된 객체를 스프레드로 전달합니다.
  return (
    <Button {...createButtonProps("클릭하세요", handleClick)} /> 
  );
}

 

 

 

register 를 스프레드 문법 없이 사용하면 아래 코드와 같이 작성할 수 있다.

const { register } = useForm();
const { name, onChange, onBlur, ref } = register('image');

return (
  <form>
    <input
      type="file"
      id="image"
      name={name}
      onChange={onChange}
      onBlur={onBlur}
      ref={ref}
    />
    <button type="submit">제출</button>
  </form>
);

 

 

register 에 value 값이 없는 이유

비제어(uncontrolled) 컴포넌트로 되어 있기 때문이다.

react-hook-form의 핵심 철학 중 하나가 렌더링 횟수를 최소화 하여 성능을 향상시키는 것이다.

 

 

이 방식은 value를 직접 관리하는 대신, ref를 사용해 DOM 요소 자체에 직접 접근하여 값을 가져온다.

 

이 방식은 입력 필드의 값이 변경될 때마다 컴포넌트 전체를 리렌더링하지 않는다.

react-hook-form은 폼 제출(submit) 시점에 필요한 값만 DOM에서 한 번에 읽어와 상태를 업데이트하기 때문에, 불필요한 리렌더링을 줄여 성능을 크게 향상시킨다.

 
 
register 를 사용해서 value 값을 가져오는 2가지 방법
 
  1) 폼 제출 시 (onSubmit)
     폼 제출 시점에 한 번만 값을 읽어오기 때문에 성능에 가장 효율적
import { useForm } from 'react-hook-form';

function MyForm() {
  const { register, handleSubmit } = useForm();
  
  // handleSubmit에 전달할 함수
  const onSubmit = (data) => {
    console.log(data); // 폼 데이터 전체가 객체 형태로 출력됩니다.
    // 예: { image: FileList, name: "이름", email: "test@example.com" }
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input type="file" {...register('image')} />
      <input type="text" {...register('name')} />
      <button type="submit">제출</button>
    </form>
  );
}

 

  2) 특정 필드 값 실시간으로 읽어오기 (watch)

  watch는 필드 값이 변경될 때마다 컴포넌트를 리렌더링하므로, 필요한 경우에만 신중하게 사용하자.

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

function MyForm() {
  const { register, watch, handleSubmit } = useForm();
  const onSubmit = (data) => console.log(data);

  // 'image' 필드의 값을 실시간으로 관찰합니다.
  const imageFile = watch('image');
  
  // imageFile은 FileList 객체이므로, 첫 번째 파일을 가져와 URL을 생성합니다.
  const previewUrl = imageFile && imageFile[0] 
    ? URL.createObjectURL(imageFile[0]) 
    : null;

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input type="file" {...register('image')} />
      
      {/* 미리보기 URL이 있으면 이미지를 렌더링합니다 */}
      {previewUrl && <img src={previewUrl} alt="미리보기" style={{ width: '200px' }} />}
      
      <button type="submit">제출</button>
    </form>
  );
}