폼을 작성할 때 폼 양식을 추가하거나 삭제하는 경우가 생깁니다. 예를 들어, 여러 명의 직원을 추가하거나 삭제하는 폼을 만들 때, useFieldArray를 사용하여 폼 데이터를 유연하게 관리할 수 있습니다. 이를 통해 폼의 양식을 동적으로 조작할 수 있습니다.
아래의 코드 예시를 통해, 직원의 이름과 나이를 받아 폼을 작성하고 추가, 삭제, 수정하는 방법을 확인해 보겠습니다.
import { useFieldArray, useForm } from "react-hook-form";
interface Form {
person: { name: string; age: string }[];
}
const Page = () => {
const { control, register } = useForm<Form>({
defaultValues: { person: [{ name: "", age: "" }] },
});
const { fields, append, remove, update } = useFieldArray({
control,
name: "person",
});
const handleAddPerson = (): void => {
append({ name: "", age: "" }, { shouldFocus: false });
};
const handleDeleteLastPerson = (): void => {
remove(fields.length - 1);
};
const handleUpdatePerson = (): void => {
update(1, { name: "수정", age: "1" });
};
return (
<>
<button type="button" onClick={handleAddPerson}>
추가
</button>
<button type="button" onClick={handleDeleteLastPerson}>
삭제
</button>
<button type="button" onClick={handleUpdatePerson}>
수정
</button>
{fields.map((field, i) => (
<>
<input key={field.id + 1} {...register(`person.${i}.name`)} />
<input key={field.id + 2} {...register(`person.${i}.age`)} />
</>
))}
</>
);
}
폼 상태를 추가, 삭제, 수정하는 기능을 각 각의 코드로 이어서 설명하겠습니다.
const handleAddPerson = (): void => {
append({ name: "", age: "" }, { shouldFocus: false });
};
추가 버튼에 연결된 handleAddPerson 함수를 통해 person 배열에 새로운 객체가 추가됩니다. 이 객체는 name과 age라는 두 속성을 기본값으로 가지고 있습니다. 추가 버튼을 클릭하면 새로 생성된 첫 번째 입력 필드에 자동으로 포커스가 이동하는데, 이 동작을 제어하려면 append 메서드의 두 번째 인자로 focusOptions를 설정할 수 있습니다.
다시 말해, append 메서드는 두 가지 파라미터를 받습니다. 첫 번째 파라미터는 추가할 객체이며, 두 번째 파라미터는 추가 후의 동작을 제어하는 옵션입니다. focusOptions를 이용하여 새로 생성된 필드에 자동 포커스를 설정하지 않을 수 있습니다.
const handleDeleteLastPerson = (): void => {
remove(fields.length - 1);
};
remove 메서드를 사용할 때, fields 배열의 길이에서 1을 뺀 값으로 마지막 요소를 삭제하는 것을 확인할 수 있습니다.
remove 메서드는 삭제할 요소의 인덱스를 인자로 받습니다. fields.length - 1을 통해 person 배열의 마지막 요소를 삭제합니다. 만약 remove의 인자를 작성하지 않으면 연결된 배열의 모든 요소가 삭제됩니다.
const handleUpdatePerson = (): void => {
update(1, { name: "수정", age: "1" });
};
update 메서드는 첫 번째 인자로 요소가 추가될 인덱스를, 두 번째 인자로는 추가할 데이터를 받습니다.
위의 코드에서 update(1, { name: "수정", age: "1" })는 Person 배열에서 인덱스가 1인 요소를 찾아 해당 요소의 데이터를 주어진 값으로 업데이트합니다. 이로써 특정 위치에 있는 폼 필드의 값을 수정할 수 있습니다. 첫 번째 인자에 전달한 인덱스에 해당하는 요소가 없으면 새로운 요소가 추가됩니다.
append(); // X
append({}); // X
append({ name: "", age: ""}); // O
append, prepend, insert, update 메서드를 사용할 때는 빈 객체를 추가할 수 없으며, 객체 내부의 모든 기본 값을 추가해주어야 합니다.
폼을 동적으로 관리하는 방법을 알게 되었습니다. 하지만 update 메서드와 setValue의 차이, Controlled Field Array에 대해서는 공식문서와 Chat GPT를 사용해도 아직 어떻게 사용해야 되는지 이해가 잘 되지 않았습니다. 더 많은 경험을 통해 알게 되는 정보들을 추가로 작성해야 될 것 같습니다. 혹시 알고 있는 분들이 댓글을 통해서 조언해 주시면 감사하겠습니다 :)
'라이브러리 > React Hook Form' 카테고리의 다른 글
[React Hook Form] Yup을 활용한 조건부 유효성 검사 (0) | 2024.02.21 |
---|---|
[React Hook Form] Yup으로 마무리하는 유효성 검사 (0) | 2024.02.20 |
[React Hook Form] Controller로 직접 만든 컴포넌트 폼 관리하기 (0) | 2024.02.14 |
[React Hook Form] FormProvider, useFormContext로 중복 코드 없이 깔끔하게 폼 관리하기 (0) | 2024.02.13 |
[React Hook Form] React Hook Form 톺아보기 (0) | 2022.05.24 |