# React Hook Form: Performante Formulare mit TypeScript **Meta-Description:** React Hook Form Masterguide für 2026. Performance-Optimierung, TypeScript-Patterns, Zod-Integration und Server Actions Support. **Keywords:** React Hook Form, Form Validation, TypeScript Forms, Zod Integration, Server Actions, React Forms, Uncontrolled Components --- ## Einführung React Hook Form ist der **Gold-Standard für Formulare in React 2026**. Durch Uncontrolled Components und Ref-basiertes State Management erreicht es minimale Re-Renders – selbst bei Formularen mit hunderten Feldern. --- ## Warum React Hook Form? ``` ┌─────────────────────────────────────────────────────────────┐ │ REACT HOOK FORM VORTEILE │ ├─────────────────────────────────────────────────────────────┤ │ │ │ Performance: │ │ ├── Uncontrolled Components (keine Re-Renders) │ │ ├── Ref-basiertes State Management │ │ ├── Isolierte Input-Subscriptions │ │ └── 100+ Felder ohne Lag │ │ │ │ Developer Experience: │ │ ├── Minimale API │ │ ├── First-Class TypeScript Support │ │ ├── Tree-Shakeable (~8KB gzipped) │ │ └── Keine Dependencies │ │ │ │ 2026 Features: │ │ ├── Server Actions Integration │ │ ├── useActionState Support │ │ └── useFormStatus Hook │ │ │ └─────────────────────────────────────────────────────────────┘ ``` --- ## Basic Setup ```typescript import { useForm } from 'react-hook-form'; interface LoginForm { email: string; password: string; rememberMe: boolean; } function LoginPage() { const { register, handleSubmit, formState: { errors, isSubmitting } } = useForm({ defaultValues: { email: '', password: '', rememberMe: false } }); const onSubmit = async (data: LoginForm) => { console.log(data); // Vollständig typisiert! await login(data); }; return (
{errors.email && {errors.email.message}} {errors.password && {errors.password.message}}
); } ``` --- ## Zod Integration ```typescript import { useForm } from 'react-hook-form'; import { zodResolver } from '@hookform/resolvers/zod'; import { z } from 'zod'; // Schema definieren const SignupSchema = z.object({ name: z.string() .min(2, 'Name zu kurz') .max(50, 'Name zu lang'), email: z.string() .email('Ungültige E-Mail'), password: z.string() .min(8, 'Mindestens 8 Zeichen') .regex(/[A-Z]/, 'Mindestens ein Großbuchstabe') .regex(/[0-9]/, 'Mindestens eine Zahl'), confirmPassword: z.string(), terms: z.literal(true, { errorMap: () => ({ message: 'Sie müssen die AGB akzeptieren' }) }) }).refine(data => data.password === data.confirmPassword, { message: 'Passwörter stimmen nicht überein', path: ['confirmPassword'] }); // Type aus Schema inferieren type SignupData = z.infer; function SignupForm() { const { register, handleSubmit, formState: { errors } } = useForm({ resolver: zodResolver(SignupSchema), mode: 'onBlur' // Validierung bei Blur }); return (
{errors.name &&

{errors.name.message}

} {errors.email &&

{errors.email.message}

} {errors.password &&

{errors.password.message}

} {errors.confirmPassword &&

{errors.confirmPassword.message}

} {errors.terms &&

{errors.terms.message}

}
); } ``` --- ## Controller für UI Libraries ```typescript import { useForm, Controller } from 'react-hook-form'; import { Select, DatePicker, Switch } from './ui-library'; interface ProfileForm { country: string; birthDate: Date; newsletter: boolean; } function ProfileForm() { const { control, handleSubmit } = useForm(); return (
{/* Select Component */} ( {errors.shipping?.name && {errors.shipping.name.message}} ); } function BillingSection() { const { register } = useFormContext(); return (
Zahlung
); } ``` --- ## Field Arrays (Dynamische Felder) ```typescript import { useForm, useFieldArray } from 'react-hook-form'; interface OrderForm { items: { productId: string; quantity: number; price: number; }[]; } function OrderForm() { const { control, register, handleSubmit, watch } = useForm({ defaultValues: { items: [{ productId: '', quantity: 1, price: 0 }] } }); const { fields, append, remove, move } = useFieldArray({ control, name: 'items' }); const watchItems = watch('items'); const total = watchItems.reduce((sum, item) => sum + (item.quantity * item.price), 0 ); return ( {fields.map((field, index) => (
))}

Gesamt: {total.toFixed(2)} €

); } ``` --- ## Server Actions Integration (Next.js 15) ```typescript // app/actions.ts 'use server'; import { z } from 'zod'; const ContactSchema = z.object({ name: z.string().min(2), email: z.string().email(), message: z.string().min(10) }); export async function submitContact(formData: FormData) { const data = ContactSchema.parse({ name: formData.get('name'), email: formData.get('email'), message: formData.get('message') }); await sendEmail(data); return { success: true }; } // app/contact/page.tsx 'use client'; import { useForm } from 'react-hook-form'; import { useActionState } from 'react'; import { submitContact } from './actions'; function ContactForm() { const { register, handleSubmit, formState: { errors } } = useForm(); const [state, formAction, isPending] = useActionState(submitContact, null); return (