Skip to content

useWatch

Observe field values reactively without registering the field. Unlike useField, useWatch does not register validators, track touched/dirty state, or provide inputProps. Use it for conditional rendering, computed display values, or side effects based on field values.

Import

ts
import { useWatch } from '@ereo/forms'

Signature

ts
// Watch a single field — returns the value
function useWatch<T extends Record<string, any>, P extends FormPath<T>>(
  form: FormStoreInterface<T>,
  path: P
): PathValue<T, P>

// Watch multiple fields — returns a tuple of values
function useWatch<T extends Record<string, any>, P extends FormPath<T>>(
  form: FormStoreInterface<T>,
  paths: P[]
): unknown[]

Parameters

NameTypeDescription
formFormStoreInterface<T>The form store (from useForm or createFormStore)
pathstringA single dot-path to watch (e.g. 'user.email')
pathsstring[]An array of dot-paths to watch

Returns

  • Single path: Returns the current value of the field. Re-renders the component when the value changes.
  • Multiple paths: Returns an array of values in the same order as the input paths. Re-renders when any of the watched values change.

Examples

Single Field

tsx
import { useWatch } from '@ereo/forms'

function PricePreview({ form }) {
  const price = useWatch(form, 'price')

  return <div className="preview">Price: ${price}</div>
}

Multiple Fields

tsx
function DateRangeDisplay({ form }) {
  const [start, end] = useWatch(form, ['startDate', 'endDate'])

  return (
    <div>
      {start && end
        ? `${start} to ${end}`
        : 'Select a date range'}
    </div>
  )
}

Conditional Rendering

Show or hide fields based on another field's value:

tsx
function ShippingForm({ form }) {
  const shippingMethod = useWatch(form, 'shippingMethod')

  return (
    <div>
      <SelectField form={form} name="shippingMethod" options={[
        { value: 'standard', label: 'Standard' },
        { value: 'express', label: 'Express' },
        { value: 'pickup', label: 'Pickup' },
      ]} />

      {shippingMethod !== 'pickup' && (
        <>
          <Field form={form} name="address" label="Shipping Address" />
          <Field form={form} name="city" label="City" />
        </>
      )}
    </div>
  )
}

Computed Values

Derive a display value from multiple fields without registering them:

tsx
function OrderSummary({ form }) {
  const [quantity, unitPrice] = useWatch(form, ['quantity', 'unitPrice'])
  const total = (Number(quantity) || 0) * (Number(unitPrice) || 0)

  return <div>Total: ${total.toFixed(2)}</div>
}

When to Use useWatch vs useField

useWatchuseField
Reactive valueYesYes
Registers validatorsNoYes
Tracks touched/dirtyNoYes
Provides inputPropsNoYes
Use caseDisplay, conditional rendering, side effectsForm inputs that need validation and state

Use useWatch when you need to read a field's value but don't need to render an input for it. Use useField when you need to bind an input element.

Released under the MIT License.