한우의 개발일기

React-hook-form에서 watch 와 useWatch 본문

React

React-hook-form에서 watch 와 useWatch

한우코딩 2024. 11. 11. 15:15

watch 와 useWatch

React Hook Form은 React에서 폼을 쉽게 관리할 수 있도록 도와주는 라이브러리입니다. 이 훅폼에는 폼의 상태를 추적하는 데 사용하는 두 가지 함수가 있습니다. 바로 useWatchwatch 함수입니다.

watch 함수

watch 함수의 동작

watch 함수는 React Hook Form에서 제공하는 중요한 기능으로, 폼 필드의 값들을 실시간으로 관찰(감시)하는 역할을 합니다.

주요 기능과 동작 원리

  1. 기본 사용법
// 모든 필드 감시
const allValues = watch();

// 특정 필드만 감시
const titleValue = watch("title");

// 여러 필드 감시
const { title, description } = watch(["title", "description"]);
  1. 동작 원리
  • watch 함수는 내부적으로 Observable 패턴을 사용합니다
  • 폼 필드의 값이 변경될 때마다 리렌더링을 트리거합니다
  • subscription 메커니즘을 통해 필드 값의 변화를 추적합니다
  1. 주요 활용 사례
// 예제: 필드 값에 따라 UI 조건부 렌더링
const watchTitle = watch("title");

return (
  <div>
    {watchTitle.length > 0 && <p>제목이 입력되었습니다!</p>}
  </div>
);

// 예제: 필드 간 연동
const watchStartDate = watch("startDate");
useEffect(() => {
  // startDate가 변경될 때 endDate 최소값 설정
  setValue("endDate", watchStartDate);
}, [watchStartDate]);
  1. 성능 최적화
// 특정 필드만 감시하여 불필요한 리렌더링 방지
const specificField = watch("title");

// 콜백을 통한 구독
watch((value, { name, type }) => {
  // 값이 변경될 때만 특정 로직 실행
  console.log(name, value, type);
});
  1. 주의사항
  • 모든 필드를 감시할 경우 성능에 영향을 줄 수 있습니다
  • 필요한 필드만 선택적으로 감시하는 것이 좋습니다
  • 불필요한 리렌더링을 피하기 위해 최적화가 필요할 수 있습니다

실제 코드에서의 활용

// 현재 코드에서는 전체 폼 값을 감시
const formValues = watch();

// 특정 컴포넌트에 필요한 값만 감시하도록 최적화 가능
const DateTimeSection = ({ watch }) => {
  const startDate = watch("startDate");
  const endDate = watch("endDate");

  // startDate, endDate 값의 변화에만 반응하는 로직
  // ...
};

useWatch

useWatch의 동작

  1. 기본 기능
// useWatch는 폼 필드의 값 변화를 구독 방식으로 관찰합니다
import { useWatch } from 'react-hook-form';

// 1. 단일 필드 감시
const title = useWatch({
  control,
  name: "title",
  defaultValue: ""
});

// 2. 다중 필드 감시 
const { title, description } = useWatch({
  control,
  name: ["title", "description"]
});

// 3. 전체 폼 감시 (권장하지 않음)
const formValues = useWatch({ control }); 
  1. 동작 원리
  • subscription 기반으로 동작
  • 해당 필드 값이 변경될 때만 리렌더링 발생
  • 필드별로 독립적인 구독 시스템 사용
  • 메모이제이션을 통한 성능 최적화
  1. 주요 활용 사례
// 필드 값에 따른 UI 조건부 렌더링
function ShowTitle({ control }) {
  const title = useWatch({
    control,
    name: "title",
    defaultValue: ""
  });

  return title ? <h1>{title}</h1> : null;
}

// 의존적인 필드 처리
function DateRange({ control }) {
  const startDate = useWatch({
    control,
    name: "startDate"
  });

  useEffect(() => {
    // startDate가 변경될 때만 실행
    setValue("endDate", startDate);
  }, [startDate]);
}
  1. 성능 최적화
// 1. 필요한 필드만 구독
function OptimizedComponent({ control }) {
  const value = useWatch({
    control,
    name: "specificField", // 필요한 필드만 지정
    defaultValue: ""  // 초기값 설정으로 첫 렌더링 최적화
  });
}

// 2. 컴포넌트 분리를 통한 최적화
function WatchComponent({ control }) {
  const value = useWatch({
    control,
    name: "field"
  });

  return <div>{value}</div>; // 이 컴포넌트만 리렌더링
}
  1. 주의사항
  • 불필요한 전체 폼 감시는 피해야 함
  • defaultValue를 적절히 활용하여 초기 렌더링 최적화
  • 컴포넌트 분리를 통한 리렌더링 범위 최소화

실제 코드에서의 활용

function AddShowsForm() {
  const { control } = useForm();

  // 각 섹션별로 필요한 필드만 감시
  return (
    <form>
      <BasicInfo />
      <DateTimeSection control={control} />
      <TagSection control={control} />
    </form>
  );
}

function DateTimeSection({ control }) {
  const startDate = useWatch({
    control,
    name: "startDate"
  });

  const endDate = useWatch({
    control,
    name: "endDate"
  });

  // startDate, endDate 변경시에만 리렌더링
  return (
    <div>
      <input {...register("startDate")} />
      <input {...register("endDate")} />
    </div>
  );
}

차이점

watch 사용시

보이듯이 모든 컴포넌트들이 리랜더링이 된다

useWatch 사용시

보이는것 처럼 watch는 폼 내부의 모든 컴포넌트가 리렌더링되는 반면
useWatch 는 변경중인 컴포넌트만 리렌더링이 됩니다

조건부로 watch를 사용할 때와 useWatch를 사용할 때의 차이는 리렌더링 제어와 관련이 있습니다. 두 접근 방식의 주요 차이는 다음과 같습니다.

  1. 조건부로 watch를 사용할 때:

    • watchuseForm에서 제공하는 메서드이기 때문에 해당 필드의 변화를 감시할 수 있지만, 컴포넌트가 리렌더링되지 않습니다.
    • 특정 필드의 값에 따라 조건부로 UI를 업데이트하고 싶다면, 상태를 이용해 추가적인 로직을 구현해야 합니다. 예를 들어, useState로 값을 설정해 변화를 감지할 수 있습니다.
    • watch는 단순히 값이 변경된 상태를 읽어오기 위한 용도로 사용될 때, 리렌더링 비용을 최소화할 수 있습니다.
  2. useWatch를 사용할 때:

    • useWatch는 React Hook Form에서 제공하는 별도의 훅으로, 특정 필드의 변경을 감지하면 해당 값을 자동으로 리렌더링합니다.
    • 따라서 값 변경에 따라 자동으로 UI 업데이트가 필요한 경우에는 useWatch를 사용하는 것이 더 간편하고 효율적입니다.
    • 또한 useWatch필드 단위로 리렌더링을 제어할 수 있어, 감시하고자 하는 필드 값이 변할 때만 컴포넌트가 리렌더링됩니다.

즉, 값 변화를 조회만 하고 싶다면 watch, 리렌더링을 통해 동적으로 UI를 업데이트하고 싶다면 useWatch를 사용하는 것이 최적의 접근 방식입니다.

'React' 카테고리의 다른 글

리액트의 초기 마운트  (0) 2025.02.13
리액트의 내부개요  (0) 2025.02.13
SSR과 CSR  (2) 2024.11.11
커스텀훅 vs 고차 컴포넌트  (0) 2024.11.11
리액트의 리렌더링  (0) 2024.11.11