React Hook Form에서 useController vs Controller

nyoung·2023년 12월 18일

react-hook-form에서 Input은 기본적으로 unControlled합니다. (https://legacy.reactjs.org/docs/uncontrolled-components.html)

register 함수를 사용하면 ref를 사용하게 됩니다. 이러한 접근 방식은 폼이나 어플리케이션에서 input의 값이 바뀔 때나 사용자가 input에 타이핑할 때 발생하는 리렌더링의 양을 줄입니다.

react-hook-form에서 Input은 기본적으로 unControlled합니다. (https://legacy.reactjs.org/docs/uncontrolled-components.html)

register 함수를 사용하면 ref를 사용하게 됩니다. 이러한 접근 방식은 폼이나 어플리케이션에서 input의 값이 바뀔 때나 사용자가 input에 타이핑할 때 발생하는 리렌더링의 양을 줄입니다.

Controller를 사용할 때에도 마찬가지로 해당 컴포넌트에서만 리렌더링 되기 때문에 리렌더링의 양을 줄입니다.

개인적으로는 Controlled Input은 Input의 Rerender을 일으키기 때문에 웬만하면 register를 사용하고 있는데, 가끔 Controlled Input을 사용할 때가 있습니다.

예를 들어 input 컴포넌트의 value 상태에 의존하는 값들이 여러 군데 존재하는 경우에, input의 값에 의존하는 여러 부분까지 매번 리렌더링이 필요하다고 생각해서 딱히 uncontrolled 한 상태에 이점이 없다고 생각해 Controlled Input을 사용했던 경험이 있습니다.

React Hook Form에서는 Controlled Input을 사용할 때에 useController / Controller 두 가지 API를 제공합니다.
두 가지 API 중 저는 아래와 같은 이유로 useController를 선호합니다.

  • 사용성 측면에서 hook으로 사용하는 useController가 더 편한 느낌이 들었습니다.
  • Controller는 Controller 컴포넌트로 감싸기 때문에, 명시적이지 않아 보여서 가독성이 좋지 않다고 느꼈습니다.
  • controlled된 데이터를 다른 곳에서도 비교적 편하게 쓸 수 있는 .(hook의 return 값이기 때문에 )

제가 느꼈던 단점은, useController를 사용 시 마다 hook을 여러 이름으로 바꿔줘야 하는게 불편했습니다.

아래에서는 ReactDatePicker를 사용하는 form에 대한 같은 기능을, 각각 useController와 Controller로 구현해보았습니다.

비교해보시면 좋을 것 같습니다.

useController

공식 문서: https://react-hook-form.com/docs/usecontroller

import React from "react";

type FormValues = {
  ReactDatepicker: string
}
function App() {
	const { handleSubmit, control } = useForm();
	const { field } = useController({
	name: "reactDatePicker",
	control
	});

	return (
	<form onSubmit={handleSubmit((data) => console.log(data))}>
		<ReactDatePicker
		onChange={field.onChange} // send value to hook form
		onBlur={field.onBlur} // notify when input is touched/blur
		selected={field.value}
		/>
		<button type="submit">제출</button>
	</form>
	);
}

Controller

공식문서: https://react-hook-form.com/docs/usecontroller/controller

import ReactDatePicker from "react-datepicker"
import { TextField } from "@material-ui/core"
import { useForm, Controller } from "react-hook-form"

type FormValues = {
  ReactDatepicker: string
}
function App() {
  const { handleSubmit, control } = useForm<FormValues>()

  return (
    <form onSubmit={handleSubmit((data) => console.log(data))}>
      <Controller
        control={control}
        name="ReactDatepicker"
        render={({ field: { onChange, onBlur, value, ref } }) => (
          <ReactDatePicker
            onChange={onChange} // send value to hook form
            onBlur={onBlur} // notify when input is touched/blur
            selected={value}
          />
        )}
      />
		<button type="submit">제출</button>
    </form>
  )
}

register을 사용하는 것과 control을 사용하는 것의 차이, useController과 Controller 관련 내용을 정리해보았습니다.

관련 discussion link 입니다.
https://github.com/orgs/react-hook-form/discussions/7852#discussioncomment-3692813

https://github.com/orgs/react-hook-form/discussions/6157

https://github.com/orgs/react-hook-form/discussions/7554

profile
점을 찍는 개발자🌱

1개의 댓글

comment-user-thumbnail
2024년 2월 26일

안녕하세요. 스터디 관련해서 메일 확인 부탁드립니다!

답글 달기