Form lớn (5+ inputs) trong RN thường gặp 2 vấn đề:
1. Controlled state ở cha → mỗi keystroke re-render toàn form, lag visible trên Android low-end.
2. Validation phức tạp (cross-field, async) viết tay rất rối.
react-hook-form giải quyết:
- State giữ trong ref nội bộ, không trong React state — không re-render component cha khi typing.
- Component nào subscribe field đó qua useController hoặc Controller mới re-render.
- Plugin Zod/Yup cho validation declarative.
import { useForm, Controller } from 'react-hook-form'
import { zodResolver } from '@hookform/resolvers/zod'
function LoginForm() {
const { control, handleSubmit } = useForm({ resolver: zodResolver(schema) })
return (
<Controller
control={control}
name="email"
render={({ field: { onChange, value } }) => (
<TextInput value={value} onChangeText={onChange} />
)}
/>
)
}Lựa chọn khác: Formik (cũ, re-render nhiều hơn), TanStack Form (mới, đang phát triển, type-safe hơn). 2026 react-hook-form vẫn là default trong RN ecosystem.
Large forms (5+ inputs) in RN typically hit two problems:
1. Controlled state in the parent → every keystroke re-renders the whole form, visible lag on low-end Android.
2. Complex validation (cross-field, async) is messy to write manually.
react-hook-form solves both:
- State lives in an internal ref, not React state — no re-render of the parent on typing.
- Only components that subscribe to that field via useController or Controller re-render.
- Zod/Yup plugins enable declarative validation.
import { useForm, Controller } from 'react-hook-form'
import { zodResolver } from '@hookform/resolvers/zod'
function LoginForm() {
const { control, handleSubmit } = useForm({ resolver: zodResolver(schema) })
return (
<Controller
control={control}
name="email"
render={({ field: { onChange, value } }) => (
<TextInput value={value} onChangeText={onChange} />
)}
/>
)
}Alternatives: Formik (older, re-renders more), TanStack Form (newer, evolving, more type-safe).
In 2026, react-hook-form remains the default in the RN ecosystem.