T
TanStack3w ago
deep-jade

What is the correct way to pass the useForm hook to another functional component in a separate file?

I have a case where I am using array mode of forms. I have various array form inputs, and I don't want to repeat typing them all in one file as They're all very similar aside from the label and the field name. Right now I create the form field component and then call it various times, passing form as a prop. Is this a correct patter? For example:
const EditableFormListField = ({ form, fieldName, label, isEditing }) => {
return (
<form.Field
name={fieldName}
mode="array"
children={(field) => (
<div className="flex flex-col gap-2">
<label htmlFor={fieldName} className="text-xl font-bold">
{label}
</label>
{field.state.value.map((_, index) => (
<form.Field
name={`${fieldName}[${index}]`}
children={(field) =>
isEditing ? (
<input
type="text"
name={field.name}
value={field.state.value}
onChange={(e) => field.handleChange(e.target.value)}
className="w-full bg-white border border-slate-200 rounded-md p-2 text-md"
/>
) : (
<p className="text-md">{field.state.value}</p>
)
}
/>
))}
</div>
)}
/>
);
};
const EditableFormListField = ({ form, fieldName, label, isEditing }) => {
return (
<form.Field
name={fieldName}
mode="array"
children={(field) => (
<div className="flex flex-col gap-2">
<label htmlFor={fieldName} className="text-xl font-bold">
{label}
</label>
{field.state.value.map((_, index) => (
<form.Field
name={`${fieldName}[${index}]`}
children={(field) =>
isEditing ? (
<input
type="text"
name={field.name}
value={field.state.value}
onChange={(e) => field.handleChange(e.target.value)}
className="w-full bg-white border border-slate-200 rounded-md p-2 text-md"
/>
) : (
<p className="text-md">{field.state.value}</p>
)
}
/>
))}
</div>
)}
/>
);
};
I want to reuse this in a detail view component and do something like this:
const form = useForm({
defaultValues: eightDReport,
onSubmit: (values) => {
console.log(values);
},
});

return (
<div>
<EditableFormListField
form={form}
fieldName="interimContainmentActions"
label="D3: Interim Containment Actions"
isEditing={isEditing}
/>

<EditableFormListField
form={form}
fieldName="rootCauseAndEscapePoints"
label="D4: Root Cause and Escape Points"
isEditing={isEditing}
/>
</div>
)
const form = useForm({
defaultValues: eightDReport,
onSubmit: (values) => {
console.log(values);
},
});

return (
<div>
<EditableFormListField
form={form}
fieldName="interimContainmentActions"
label="D3: Interim Containment Actions"
isEditing={isEditing}
/>

<EditableFormListField
form={form}
fieldName="rootCauseAndEscapePoints"
label="D4: Root Cause and Escape Points"
isEditing={isEditing}
/>
</div>
)
1 Reply
extended-salmon
extended-salmon3w ago
withForm helps you structure the expected type

Did you find this page helpful?