Form Management
Setting Values
The setValue function is versatile and supports multiple usage patterns:
Direct Event Handler
The most common usage - pass it directly to onChange:
<input name="email" onChange={setValue} value={values.email || ''} />Programmatic Updates
Set values programmatically with field path and value:
setValue('email', 'user@example.com')Curried Function
Create a setter for a specific field:
const setEmail = setValue('email')
setEmail('user@example.com')Nested Values
Use dot notation for nested objects:
<input
name="address.city"
onChange={setValue}
value={values.address?.city || ''}
/>Array Values
Use bracket notation for arrays:
<input
name="items[0].title"
onChange={setValue}
value={values.items?.[0]?.title || ''}
/>Initial Values
Set initial values when creating the form:
const { Form, values } = useForm({
initialValues: {
name: 'John Doe',
email: 'john@example.com',
},
})Resetting on Initial Values Change
When initialValues changes, the form automatically resets:
const { Form } = useForm({
initialValues: userProfile, // When userProfile changes, form resets
})TIP
Initial values are compared deeply, so you don't need to memoize them. However, using useMemo might improve performance in some cases.
Resetting the Form
Use the reset function to restore form to initial state:
const { Form, reset, values } = useForm({
initialValues: { name: '', email: '' },
onSubmit: (values, { reset }) => {
api.submitForm(values)
reset() // Clear form after submission
},
})Reset with New Values
Pass new initial values when resetting:
reset({ name: 'New Name', email: 'new@email.com' })Tracking Changes
isDirty Flag
Check if any field has been modified:
const { Form, isDirty } = useForm()
return (
<Form>
{/* ... fields ... */}
<button disabled={!isDirty}>Save Changes</button>
</Form>
)Dirty Fields List
Get a list of all modified fields:
const { dirtyFields } = useForm()
console.log(dirtyFields) // ['name', 'email']Auto-Subscribable
dirtyFields is auto-subscribable. If you don't read it from the hook, your component won't re-render when it changes.
Managing Touched State
Mark fields as touched (usually on blur):
const { Form, setTouched, values } = useForm()
return (
<Form>
<input
name="email"
value={values.email || ''}
onChange={setValue}
onBlur={setTouched} // Marks field as touched on blur
/>
</Form>
)Programmatic Touch
setTouched('email', true) // Mark as touched
setTouched('email', false) // Mark as untouchedCurried Version
const touchEmail = setTouched('email')
touchEmail(true)Form State Access
Access the complete form state with useFormState:
import { useFormState } from 'yet-another-form/react'
function SubmitButton() {
const { isDirty, isValid, isSubmitting } = useFormState()
return (
<button disabled={!isDirty || !isValid || isSubmitting}>
{isSubmitting ? 'Saving...' : 'Save'}
</button>
)
}TIP
useFormState must be used within a <Form> component or you need to pass the form context manually.
