MDK Logo

Forms

Form state and validation hooks

Hooks for form state management and validation.

Package

@tetherto/mdk-react-devkit

Prerequisites

  • Install the packages
npm install \
  @tetherto/mdk-react-devkit \
  @tetherto/mdk-react-adapter \
  @tetherto/mdk-ui-foundation

Hooks

@tetherto/mdk-react-devkit

Used by form primitives

import { useFormField } from '@tetherto/mdk-react-devkit'

When to use useFormField

Use useFormField inside a custom form-field child that needs the current field's ID, validation state, or ARIA attributes. Standard pre-built fields already consume this context internally.

useFormField workflow

FormField provides the field context, FormItem provides the generated IDs, and custom descendants read that combined context through useFormField.

useFormField prerequisites

The hook must be rendered inside a Form, which supplies react-hook-form's context, and beneath a FormField, which supplies the field. Both are enforced: without Form the hook throws as it reads the form context, and without FormField it throws useFormField must be used within a <FormField>.

FormItem is optional. It only contributes the element id used to wire labels and messages, and the hook falls back to an empty id without it.

It is not a standalone form-state hook and does not replace useForm.

useFormField example

import { useForm } from 'react-hook-form'
import {
  Form,
  FormControl,
  FormField,
  FormItem,
  FormLabel,
  useFormField,
} from '@tetherto/mdk-react-devkit'

const FieldStatusDot = () => {
  const { invalid, isDirty } = useFormField()
  const state = invalid ? 'error' : isDirty ? 'dirty' : 'clean'

  return <span aria-label={`Field is ${state}`} data-state={state} />
}

const NameForm = () => {
  const form = useForm({ defaultValues: { name: '' } })

  return (
    <Form form={form}>
      <FormField
        control={form.control}
        name="name"
        render={({ field }) => (
          <FormItem>
            <FormLabel>Name</FormLabel>
            <FormControl>
              <input {...field} />
            </FormControl>
            <FieldStatusDot />
          </FormItem>
        )}
      />
    </Form>
  )
}
@tetherto/mdk-react-devkit

Reset form state

import { useFormReset } from '@tetherto/mdk-react-devkit'

When to use useFormReset

Use useFormReset when resetting a react-hook-form form also needs before/after callbacks or a reusable dirty-state guard. Call the form object's reset method directly when no lifecycle behaviour is needed.

useFormReset workflow

Create the form with useForm, pass that instance to useFormReset, then wire the returned resetForm handler to a reset or cancel action. The hook reports isDirty from the same form state so the action can be disabled until values change.

useFormReset prerequisite

The hook requires a configured react-hook-form instance. It composes with Form and fields such as FormInput; it does not create or submit the form.

useFormReset example

import { useForm } from 'react-hook-form'
import { Button, Form, FormInput, useFormReset } from '@tetherto/mdk-react-devkit'

type MinerFields = { name: string; ip: string }

const MinerEditForm = ({ onSubmit }: { onSubmit: (values: MinerFields) => void }) => {
  const form = useForm<MinerFields>({ defaultValues: { name: '', ip: '' } })
  const { resetForm, isDirty } = useFormReset({
    form,
    onAfterReset: () => console.log('Form reset'),
  })

  return (
    <Form form={form} onSubmit={form.handleSubmit(onSubmit)}>
      <FormInput control={form.control} name="name" label="Name" />
      <FormInput control={form.control} name="ip" label="IP address" />
      <Button type="submit">Save</Button>
      <Button type="button" onClick={resetForm} disabled={!isDirty}>
        Reset
      </Button>
    </Form>
  )
}
@tetherto/mdk-react-devkit

Import the public APIs on this page from @tetherto/mdk-react-devkit.

useFormField

Read-only context hook for form field children — returns the field's id, error state, and ARIA attributes

() => UseFormFieldReturn

useFormReset

Hook to handle form reset with callbacks

<TFieldValues extends FieldValues = FieldValues>({ form, onBeforeReset, onAfterReset, }: UseFormResetOptions<TFieldValues>) => UseFormResetReturn

On this page