React Native Form Handling
This guide explains two popular ways to handle forms in a React Native TypeScript project:
- Formik + Yup
- React Hook Form + Zod
Both provide form state management and validation, but with different approaches.
1. Project Setup
Create a new Expo TypeScript project:
npm install -g expo-cli
expo init MyFormApp --template expo-template-blank-typescript
cd MyFormApp
2. Formik + Yup (Legacy Approach)
Formik is a popular form library for React and React Native.
Yup is a schema validation library that integrates seamlessly with Formik.
Installation
- npm install:
npm install formik yup @types/yup
- expo install:
npx expo install formik yup @types/yup
Example Usage
import React from 'react'
import { Button, Text, TextInput, View } from 'react-native'
import { Formik } from 'formik'
import * as Yup from 'yup'
const SignupSchema = Yup.object().shape({
email: Yup.string().email('Invalid email').required('Required'),
password: Yup.string().min(6, 'Too Short!').required('Required'),
})
export default function FormikFormExample() {
return (
<Formik
initialValues={{email: '', password: ''}}
validationSchema={SignupSchema}
onSubmit={values => console.log(values)}
>
{({handleChange, handleBlur, handleSubmit, values, errors, touched}) => (
<View style={styles.container}>
<TextInput
placeholder="Email"
onChangeText={handleChange('email')}
onBlur={handleBlur('email')}
value={values.email}
style={styles.input}
/>
{errors.email && touched.email ? <Text style={styles.error}>{errors.email}</Text> : null}
<TextInput
placeholder="Password"
secureTextEntry
onChangeText={handleChange('password')}
onBlur={handleBlur('password')}
value={values.password}
style={styles.input}
/>
{errors.password && touched.password ? <Text style={styles.error}>{errors.password}</Text> : null}
<Button onPress={handleSubmit as any} title="Submit"/>
</View>
)}
</Formik>
)
}
const styles = StyleSheet.create({
container: {padding: 20},
input: {height: 40, borderColor: 'gray', borderWidth: 1, marginBottom: 10, paddingHorizontal: 10},
error: {color: 'red'}
})
References
3. React Hook Form + Zod (Modern Approach)
React Hook Form is a lightweight form library using uncontrolled components.
Zod is a TypeScript-first schema validation library that works well with React Hook Form.
Installation
- npm install:
npm install react-hook-form zod @hookform/resolvers
- expo install:
npx expo install react-hook-form zod @hookform/resolvers
Example Usage
import React from 'react'
import { View, TextInput, Button, Text, StyleSheet } from 'react-native'
import { useForm, Controller } from 'react-hook-form'
import { zodResolver } from '@hookform/resolvers/zod'
import * as z from 'zod'
const schema = z.object({
email: z.string().email('Invalid email'),
password: z.string().min(6, 'Password too short'),
})
type FormData = z.infer<typeof schema>
export default function HookFormExample() {
const {control, handleSubmit, formState: {errors}} = useForm<FormData>({
resolver: zodResolver(schema)
})
const onSubmit = (data: FormData) => console.log(data)
return (
<View style={styles.container}>
<Controller
control={control}
name="email"
render={({field: {onChange, onBlur, value}}) => (
<>
<TextInput
placeholder="Email"
onChangeText={onChange}
onBlur={onBlur}
value={value}
style={styles.input}
/>
{errors.email && <Text style={styles.error}>{errors.email.message}</Text>}
</>
)}
/>
<Controller
control={control}
name="password"
render={({field: {onChange, onBlur, value}}) => (
<>
<TextInput
placeholder="Password"
secureTextEntry
onChangeText={onChange}
onBlur={onBlur}
value={value}
style={styles.input}
/>
{errors.password && <Text style={styles.error}>{errors.password.message}</Text>}
</>
)}
/>
<Button onPress={handleSubmit(onSubmit)} title="Submit"/>
</View>
)
}
const styles = StyleSheet.create({
container: {padding: 20},
input: {height: 40, borderColor: 'gray', borderWidth: 1, marginBottom: 10, paddingHorizontal: 10},
error: {color: 'red'}
})
References
4. Summary
| Feature | Formik + Yup | React Hook Form + Zod |
|---|---|---|
| Approach | Controlled components | Uncontrolled components |
| TypeScript support | Good (requires some typing) | Excellent (Zod is TS-first) |
| Validation | Yup schemas | Zod schemas via resolver |
| Performance | Slightly slower on large forms | Lightweight and fast |
| More Modern | Legacy | Modern |
Both libraries are excellent choices; it depends on your project needs and preference.