Forms are an essential part of any mobile application, and handling them efficiently can enhance user experience and application performance. In this blog, we'll explore the best practices for managing forms in React Native using react-hook-form and Yup for validation.
Why Use React Hook Form?
React Hook Form is a lightweight library that helps manage form states and validation with minimal re-renders. It offers better performance compared to controlled components and integrates seamlessly with Yup, a schema validation library.
Key Benefits:
- Minimal re-renders.
- Improved performance.
- Simple and declarative validation.
- Integrates well with existing UI components.
Setting Up the Project
To get started, install the necessary dependencies:
yarn add react-hook-form @hookform/resolvers yup
react-hook-form
hookform-resolvers
yup
Defining Validation Schemas with Yup
Using Yup, we define schemas for form validation. Here are a few common scenarios:
1. Login Form Validation
import * as yup from 'yup';
export const loginSchema = yup.object({
username: yup.string().min(3, 'Username must be at least 3 characters').required('Username is required'),
password: yup.string().min(5, 'Password must be at least 5 characters').required('Password is required'),
});
2. Forgot Password Validation
export const forgotPasswordSchema = yup.object({
username: yup.string().required('Username is required'),
});
3. Request Time Off Validation
export const requestTimeOffSchema = yup.object({
leaveType: yup.object().required('Please select leave type'),
dateRange: yup.object().required('Please select a date'),
});
4. Bank Letter Validation
export const bankLetterSchema = yup.object({
leaveType: yup.object().required('Please select letter type'),
bankName: yup.object().required('Please select a bank'),
comments: yup
.string()
.max(50, 'Comments should not exceed 50 characters')
.matches(/^[a-zA-Z0-9 .]*$/, 'Comments should not contain special characters except .')
.nullable(),
});
5. Incident Report Validation
import moment from 'moment';
const timeAndDateOfIncident = {
dateOfIncident: yup
.object({ startDate: yup.date().required('Please select date of incident') })
.required('Please select date of incident'),
timeOfIncident: yup
.string()
.required('Please select time of incident')
.test('time-validation', 'Time should not exceed current time', function (value) {
const { startDate } = this.parent.dateOfIncident;
if (!startDate || !value) return true;
const currentDate = moment();
const selectedDate = moment(startDate);
const selectedTime = moment(value, 'ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');
return !(selectedDate.isSame(currentDate, 'day') && selectedTime.isAfter(currentDate));
}),
};
export const goodObservation = yup.object({
incidentLocation: yup.object().required('Please select location'),
comments: yup.string().required('What you observed is required'),
...timeAndDateOfIncident,
});
6. Attendance Validation
export const singleShiftAttendance = yup.object({
f1: yup
.string()
.required('Check-in time is required')
.test('is-lower-than-f2', 'Check-in time must be less than Check-out time', function (value) {
const { f2, f1nextDay, f2nextDay } = this.parent;
if (!value || !f2 || f1nextDay || f2nextDay) return true;
return new Date(value) < new Date(f2);
}),
f2: yup
.string()
.required('Check-out time is required')
.test('is-greater-than-f1', 'Check-out time must be greater than Check-in time', function (value) {
const { f1, f1nextDay, f2nextDay } = this.parent;
if (!value || !f1 || f1nextDay || f2nextDay) return true;
return new Date(value) > new Date(f1);
}),
reason: yup.object().required('Please select reason'),
});
Implementing Forms with React Hook Form
Now, let's integrate React Hook Form with our validation schemas.
Example: Login Form Implementation
import React from 'react';
import { View, Text, TextInput, Button } from 'react-native';
import { useForm, Controller } from 'react-hook-form';
import { yupResolver } from '@hookform/resolvers/yup';
import { loginSchema } from './validationSchemas';
const LoginForm = () => {
const {
control,
handleSubmit,
formState: { errors },
} = useForm({
resolver: yupResolver(loginSchema),
});
const onSubmit = (data) => {
console.log('Login Data:', data);
};
return (
<View>
<Text>Username</Text>
<Controller
control={control}
name="username"
render={({ field: { onChange, value } }) => (
<TextInput
style={{ borderWidth: 1, padding: 10 }}
onChangeText={onChange}
value={value}
/>
)}
/>
{errors.username && <Text style={{ color: 'red' }}>{errors.username.message}</Text>}
<Text>Password</Text>
<Controller
control={control}
name="password"
render={({ field: { onChange, value } }) => (
<TextInput
style={{ borderWidth: 1, padding: 10 }}
secureTextEntry
onChangeText={onChange}
value={value}
/>
)}
/>
{errors.password && <Text style={{ color: 'red' }}>{errors.password.message}</Text>}
<Button title="Login" onPress={handleSubmit(onSubmit)} />
</View>
);
};
export default LLoginForm
Conclusion
Using React Hook Form and Yup together simplifies form handling in React Native. It ensures better performance, maintainability, and user experience. By following best practices, you can create scalable and efficient forms for your mobile applications.
Stay tuned for more tips on building robust React Native apps!
Top comments (0)