My App
API Reference

useMuiForm Hook

API reference for the useMuiForm hook

useMuiForm

The main hook for creating and managing forms with Material-UI components. Built on top of react-hook-form with MUI-specific enhancements.

Import

import { useMuiForm } from 'usemuiform'

Type Signature

function useMuiForm<TFieldValues extends FieldValues = FieldValues>(
  options?: UseFormProps<TFieldValues>
): UseMuiFormReturn<TFieldValues>

Parameters

Accepts all react-hook-form useForm options. Commonly used options include:

  • defaultValues - Initial form values
  • mode - Validation strategy (onChange, onBlur, onSubmit, etc.)
  • resolver - Schema validation (Zod, Yup, etc.)

See the react-hook-form documentation for the complete list of options.

Return Value

Returns all react-hook-form methods with the following MUI-specific enhancements:

register

This is the key MUI-specific enhancement. Enhanced register function that returns MUI-compatible props instead of standard HTML input props.

function register<Name extends Path<TFieldValues>>(
  name: Name,
  options?: RegisterOptions<TFieldValues, Name>
): RegisterMuiReturn<TFieldValues, Name>

Parameters

name: Field name or dot-notation path for nested fields

register('email')           // Simple field
register('person.name')     // Nested field
register('address.city')    // Deeply nested field

options: Standard react-hook-form validation options (required, pattern, validate, etc.)

Return Value

This is what makes useMuiForm unique - instead of standard HTML props, you get MUI-compatible props that are fully controlled by react-hook-form:

{
  name: string           // Field name
  onChange: function     // Change handler (supports both events and direct values)
  onBlur: function       // Blur handler
  error: boolean         // Whether field has validation error
  helperText: string     // Error message (empty if no error)
  inputRef: RefObject    // React ref for the input

  // For non-boolean fields:
  value: any             // Current value (controlled)

  // For boolean fields (checkboxes, switches):
  checked: boolean       // Current checked state (controlled)
}

Under the hood, register uses watch(name) from react-hook-form to derive the current value for the field, so the value / checked props stay in sync with the form state in real time (including reset, setValue, etc.).

The key differences from react-hook-form's register:

  • Returns error (boolean) and helperText (string) instead of requiring you to access formState.errors
  • Always provides controlled value/checked props suitable for MUI components
  • The onChange handler works with both MUI events and direct values (e.g. onChange(value) from pickers)

registerHtml

Access to the original react-hook-form register function for use with native HTML inputs:

const { registerHtml } = useMuiForm<FormState>({
  defaultValues: { email: '' }
})

// Use for native HTML inputs
<input {...registerHtml('email')} />

Other Methods

All other react-hook-form methods are available unchanged:

Example

The basic usage remains the same, but now components receive controlled value/checked props automatically:

import { useMuiForm } from 'usemuiform'
import { TextField, Button, Stack } from '@mui/material'

type FormState = {
  email: string
  name: string
}

function MyForm() {
  const { register, handleSubmit, reset } = useMuiForm<FormState>({
    defaultValues: { email: '', name: '' }
  })

  const onSubmit = (data: FormState) => {
    console.log('Form data:', data)
  }

  return (
    <Stack component="form" spacing={2}>
      <TextField
        label="Email"
        {...register('email', {
          required: 'Email is required',
          pattern: {
            value: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i,
            message: 'Invalid email address'
          }
        })}
      />

      <TextField
        label="Name"
        {...register('name', { required: 'Name is required' })}
      />

      <Stack direction="row" spacing={1}>
        <Button variant="contained" onClick={handleSubmit(onSubmit)}>
          Submit
        </Button>
        <Button variant="text" onClick={() => reset()}>
          Reset
        </Button>
      </Stack>
    </Stack>
  )
}

See Also

On this page