Fields
Within Formula, every part of your form data is considered a field, not just primitive types like string that can be
associated with a form control. That means fields can contain other fields. In this form data:
type Post = { content: string tags: Array<{ label: string }>}… content is a field, but so is tags, and tags[0], and tags[0].label.
Accessing a field
Section titled “Accessing a field”The form instance returned by useForm is a function you can call to access individual fields in
a type-safe way.
const form = useForm({ initialValues: { username: "", password: "" }, submit: values => login(values)});// ✅ type is FormField<string>const usernameField = form("username");
// ❌ Argument of type "title" is not assignable to// parameter of type "username" | "password"const unknownField = form("title");A field is basically a type-safe reference to a slice of the form data. It doesn’t contain any data, but it knows
how to get a snapshot and how to subscribe to updates. For that reason, Fields have a getData() function, but they
don’t (and couldn’t) have a .data property.
The reason the name form is used above, rather than say getField, is because form is also an object with
methods like submit and reset. It might be a surprise to some beginners that
JavaScript functions can also define
properties.
const form = useForm({/* ... */});const usernameField = form("username");form.reset();form.submit();Nested fields
Section titled “Nested fields”Fields work in exactly the same way as form above: they’re callable functions which also have methods.
const form = useForm({ initialValues: { address: { number: "", street: "", city: "" } }});// ✅ type is FormField<string>const streetField = form("address")("street");form("address").setData({ number: "123", street: "Fake St", city: "" });Subscribing to a field’s data
Section titled “Subscribing to a field’s data”As we covered, a field is a reference to a slice of form data, rather than the form data itself. It can provide a snapshot, but how can we subscribe to the value?
For a lot of simple forms, often you don’t need to. The built-in controls like <Input> accept a
FormField and will create a subscription and bind that value to the control.
If you need to implement your own controls, or you need to use a value somewhere besides a controlled input, then you
can subscribe to the field’s data using the useFieldData hook.