티스토리 뷰

TIL

react-hook-form 나홀로 정리하기

윤미주 2024. 7. 2. 19:26

react-hook-form 사용하면서 배운 것들 정리하기.

 

1. type을 number로 받아 value에 저장해야할때

금액을 받는 폼을 만들어 등록 시, 수정 시에 사용하려고 했다.

 

< 기존 코드 >

import { ReHomeFormType } from "@/types/register/register";
import React from "react";
import { useFormContext } from "react-hook-form";

interface AdoptionFeeFormChildrenType {
  text?: string;
  defaultValue?: number;
}

export default function AdoptionFeeForm({
  text,
  defaultValue,
}: AdoptionFeeFormChildrenType) {
  const { register, setValue, getValues } = useFormContext<ReHomeFormType>();

  const handleInput = (event: React.ChangeEvent<HTMLInputElement>) => {
    const value = event.target.value;
    console.log(typeof value)
    setValue("adoptionFee", value ? Number(value) : 0);
  };

  return (
    <div className="mx-6 md:mx-40 mt-2  flex flex-col gap-1 ">
      <div className="flex flex-col">
        <label htmlFor="name" className="text-sm md:text-base">
          {text}
        </label>
        <input
          type="number"
          defaultValue={defaultValue}
          placeholder={`${text}를 입력해주세요`}
          {...register("adoptionFee", {
            required: "값이 입력되지 않았습니다.",
            min: {
              value: 0,
              message: "음수는 입력할 수 없습니다.",
            },
            onChange: handleInput,

            value:
              getValues("adoptionFee") !== 0
                ? getValues("adoptionFee")
                : undefined,
          })}
          className="border-2 border-border-color rounded-md text-sm md:text-base py-2 px-4 mt-2 focus:outline-none focus:border-main-color"
        />
      </div>
    </div>
  );
}

 

onChange로 사용자가 입력한 값을 추적해 setValue로 값을 담았다.

하지만 event를 이용했기에 input type을 number로 하더라도 string으로 받으므로 number로 변환해주어야 했다.

이렇게 사용하다 보니 useWatch를 이용해 변경된 값을 사용하려고 할때,

 

숫자로 변환한 초기값 ` type: number `

useWatch에서 추적한 값은 ` type: string `

 

으로 비교하게 되어 실제 값이 바뀌지 않았음에도 불구하고 변경된 값이라고 인지하게 되었다. 

 

아래는 useWatch를 활용해 변경된 값을 console.log로 확인했을때 값.

 

< 변경된 코드 >

`valueAsNumber: true` 추가하기

import { ReHomeFormType } from "@/types/register/register";
import React from "react";
import { useFormContext } from "react-hook-form";

interface AdoptionFeeFormChildrenType {
  text?: string;
  defaultValue?: number;
}

export default function AdoptionFeeForm({
  text,
  defaultValue,
}: AdoptionFeeFormChildrenType) {
  const { register } = useFormContext<ReHomeFormType>();

  return (
    <div className="mx-6 md:mx-40 mt-2  flex flex-col gap-1 ">
      <div className="flex flex-col">
        <label htmlFor="name" className="text-sm md:text-base">
          {text}
        </label>
        <input
          type="number"
          defaultValue={defaultValue}
          placeholder={`${text}를 입력해주세요`}
          {...register("adoptionFee", {
            required: "값이 입력되지 않았습니다.",
            min: {
              value: 0,
              message: "음수는 입력할 수 없습니다.",
            },

            valueAsNumber: true,
          })}
          className="border-2 border-border-color rounded-md text-sm md:text-base py-2 px-4 mt-2 focus:outline-none focus:border-main-color"
        />
      </div>
    </div>
  );
}

 

onChange로 입력된 값을 추적할 필요 없이 valueAsNumber를 활용하면 setValue와 같은 역할을 하면서도

type을 number로 저장도 해준다. 

변경 후에는 type으로 인해 값이 변경되었다고 인지하지 않았고 코드도 간결해졌다.

 

 

 

'TIL' 카테고리의 다른 글

axiosInstance 리펙토링하기  (0) 2024.07.06
토큰 만료처리하기  (0) 2024.07.06
무한스크롤 쉽게 구현하기  (0) 2024.06.25
Zustand 이용해 컨펌창 만들기  (2) 2024.06.24
Axios에서 url 요청보낼 때 주의할 점  (0) 2024.06.07