T
TanStack5mo ago
quickest-silver

How to use form composition ui component blocks for subfields

I follow examples and its straightforward and nice to be able to reuse declare field components, like field.TextField etc, but in the example again, its not certain how to use those ui components for subfields when form has array fields.
const field = useFieldContext<string>()
const field = useFieldContext<string>()
this will get whole field and not subfields, I tried to pass FieldApi as param but it'll create a lot of generic type thing. So my question is how should I use ui components i registered for composition in array subfields
2 Replies
generous-apricot
generous-apricot5mo ago
Depends on what you want to do. 1. You want to have the field component of string for arrays Solution: Combine AppFields with the array mode. On each field, you can add your custom field component.
<form.Field name="people" mode="array">
{peopleField => peopleField.state.value.map((person, i) => (
<form.AppField name={`people[${i}].firstName`}>
{nameField => <nameField.YourTextField />}
</form.AppField>
))}
</form.Field>
<form.Field name="people" mode="array">
{peopleField => peopleField.state.value.map((person, i) => (
<form.AppField name={`people[${i}].firstName`}>
{nameField => <nameField.YourTextField />}
</form.AppField>
))}
</form.Field>
2. You have an object and want a custom field component combining the subfields Solution: Fields are not restricted to primitive types.
type WeekPattern = {
monday: true,
tuesday: true,
wednesday: true,
thursday: true,
friday: true,
saturday: true,
sunday: true
}

// in your field component
const field = useFieldContext<WeekPattern>();

field.state.value // type: WeekPattern

// changing fields is handled by updaters. Don't modify the
// given object directly, rule of React hooks!
field.handleChange(previousWeek => ({ ...previousWeek, monday: false }))


// in your forms
type FormValues = {
week: WeekPattern
}

const form = useAppForm({
defaultValues: {
week: { /* ... */ }
} as FormValues
});

<form.AppField name="week">
{field => {
// WeekPatternField has WeekPattern context
return <field.WeekPatternField />
}}
</form.AppField>
type WeekPattern = {
monday: true,
tuesday: true,
wednesday: true,
thursday: true,
friday: true,
saturday: true,
sunday: true
}

// in your field component
const field = useFieldContext<WeekPattern>();

field.state.value // type: WeekPattern

// changing fields is handled by updaters. Don't modify the
// given object directly, rule of React hooks!
field.handleChange(previousWeek => ({ ...previousWeek, monday: false }))


// in your forms
type FormValues = {
week: WeekPattern
}

const form = useAppForm({
defaultValues: {
week: { /* ... */ }
} as FormValues
});

<form.AppField name="week">
{field => {
// WeekPatternField has WeekPattern context
return <field.WeekPatternField />
}}
</form.AppField>
quickest-silver
quickest-silverOP5mo ago
nice, i didn't think this, thanks

Did you find this page helpful?