1. やりたいこと
React Hook Formを使ったフォームにおいて、動的に増加するインプット要素に対応したものを作りたい
useFieldArrayを使って、「add」ボタンを押下するとCareersにインプット要素が増えていくフォームを実現する
2. コード
Form.tsx
import { Input, VStack, Select } from '@chakra-ui/react'
import { FormProvider, useForm } from "react-hook-form";
import { Careers } from './careers';
enum GenderEnum {
female = "female",
male = "male",
other = "other",
}
interface IFormInput {
firstName: string
lastName: string
backGround: {
careers: { value: string }[]
}
gender: GenderEnum
}
export function PersonalForm() {
const methods = useForm<IFormInput>({
defaultValues: {
firstName: "",
lastName: "",
backGround: {
careers: [
{ value: "" }
],
},
gender: GenderEnum.female
}
})
return (<>
<FormProvider {...methods}>
<form >
<VStack align='stretch'>
<div>
<label>Name</label>
<VStack align='stretch'>
<Input {...methods.register("firstName")} placeholder="first name" />
<Input {...methods.register("lastName")} placeholder="last name" />
</VStack>
</div>
<div>
<Careers />
</div>
<div>
<label>Gender Selection</label>
<Select {...methods.register("gender")}>
<option value="female">female</option>
<option value="male">male</option>
<option value="other">other</option>
</Select>
</div>
</VStack>
</form>
</FormProvider>
</>
);
}
Career.tsx
import { Input, Button, VStack } from '@chakra-ui/react'
import { useFieldArray, useFormContext } from "react-hook-form";
export function Careers() {
const { register, control } = useFormContext()
const { fields, append } = useFieldArray({
name: "backGround.careers",
control: control,
});
return (<>
<label>Careers</label>
<VStack align='stretch'>
{fields.map((field, index) => (
<Input
key={field.id}
{...register(`backGround.careers.${index}.value`)}
/>
))}
</VStack>
<Button size={"xs"} onClick={() => { append({ value: "" }) }} style={{ float: "right", marginTop: "5px" }}>add</Button>
</>
);
}