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.