Eun_Frontend
  • [React Hook Form] React Hook Form 공부 - 9 (useFieldArray 함수로 즉석에서 FormValues 항목 늘리고 줄이기) [7/25 study]
    2024년 07월 25일 05시 33분 22초에 업로드 된 글입니다.
    작성자: 동혁이

    React Hook Form 공부 - 9

     

    useFieldArray 함수로 즉석에서 FormValues 항목 늘리고 줄이기

    phoneNumbers는 딱 2개만 입력받을 수 있게 지정했는데요. 

    React-Hook-Form에는 useFieldArray라는 강력한 함수를 제공해 줍니다. 

    UI상에서 가변적으로 입력 항목을 늘리고 줄일 수 있는데요. phNumbers라는 항목으로 예제를 만들어 보겠습니다.

    type FormValues = {
      username: string;
      email: string;
      social: {
        github: string;
        twitter: string;
      };
      phoneNumbers: string[];
      phNumbers: {
        number: string;
      }[];
    };
    
    export default function MyForm() {
      const {
        register,
        control,
        handleSubmit,
        formState: { errors },
      } = useForm<FormValues>({
        defaultValues: {
          username: "IU",
          email: "",
          social: {
            github: "",
            twitter: "",
          },
          phoneNumbers: ["", ""],
          phNumbers: [{ number: "" }],
        },
      });

    위와 같이 phNumbers 항목을 객체의 배열로 지정했고, defaultValues 안에는 한개만 명시했습니다. 

    defaultValues안에는 최소 한 개는 명시되어 있어야 합니다. 

    defaultValues까지 지정했으면 useFieldArray 훅을 실행해야 하는데요.

     

    import { useForm, useFieldArray } from "react-hook-form";
    
    export default function MyForm() {
      const {
        register,
        control,
        handleSubmit,
        formState: { errors },
      } = useForm<FormValues>({
        defaultValues: {
          username: "IU",
          email: "",
          social: {
            github: "",
            twitter: "",
          },
          phoneNumbers: ["", ""],
          phNumbers: [{ number: "" }],
        },
      });
    
      const { fields, append, remove } = useFieldArray({
        name: "phNumbers",
        control: control,
      });
    
      ...
      ...
      ...
    }

    useFieldArray 훅에는 FormValues의 name 값과, React-Hook-Form의 컨트롤 값이 control을 넘겨줘야 합니다. 

    useFieldArray가 리턴하는 객체에는 fields, append, remove 항목이 있는데요. 

    JSX 부분을 작성하면서 알아보겠습니다. 

    JSX 부분에서는 즉석에서 추가, 삭제하는 로직이 들어갑니다. 

    wireless 부분 다음에 위치합니다.

     

    <label htmlFor="wireless">Wireless</label>
    <input type="text" id="wireless" {...register("phoneNumbers.1")} />
    
    <div>
      <label>List of Phone Numbers</label>
      <div>
        {fields.map((field, index) => {
          return (
            <div key={field.id}>
              <input
                type="text"
                {...register(`phNumbers.${index}.number`)}
              />
              {index > 0 && (
                <button type="button" onClick={() => remove(index)}>
                  Remove
                </button>
              )}
            </div>
          );
        })}
        <button type="button" onClick={() => append({ number: "" })}>
          Add phone number
        </button>
      </div>
    </div>
    
    <button>Submit</button>

     

    코드를 조금 살펴보면 useFieldArray가 제공해주는 fields 라는 배열을 이용해서 map으로 iterate한 다음에, 

    각 iterate된 항목에 input 태그를 넣어 줬습니다. 

    넣어준 input 태그에는 register 함수를 사용해서 react-hook-form에 등록을 시켰는데요. 

    phNumbers.${index}.number 형식으로 진행했습니다. 

    그리고 맨 밑에 "Add phone number" 버튼을 만들었는데요. 

    이 버튼을 누르면 useFieldArray 훅이 리턴 하는 append 함수를 작동시킵니다. 

    append 함수는 말 그대로 fields 배열에 항목을 하나 추가한다는 뜻입니다. 

    브라우저에서 보면 아래 그림처럼 계속 input 태그가 늘어나는 걸 볼 수 있습니다.

     

    그리고 useFieldArray 가 리턴 하는 remove 함수도 적용했는데요. 

    remove 함수에는 index 숫자를 넣어주면 해당 index의 항목을 fields 배열에서 삭제하게 됩니다. 최종 실행 결과입니다.

    useFieldArray 훅은 정말 강력한 기능을 수행할 수 있네요.

    댓글