React-Hook-Form is a node package which simplifies creating react native forms.
Introduction
Forms are the basic need of any application whether it is web based, Android, iOS or even React Native. There are many parameters involved in forms, like –
- Type of field
- If it is mandatory
- Maximum or minimum length it will support
- If it needs to be obfuscated
- What’s the error? and where to show them? etc.
It’s challenging and error prone to deal with all these issues along with maintaining the code base.
For React and React Native, we can create forms using different libraries. We could create codes from scratch, but in this article we are going to use React-Hook-Form.
If you want to learn about react native animation then use this guide.
Installing React-Hook-Form
You can use npm
or yarn
to install the library. Use either of these commands –
npm install react-hook-form
yarn add react-hook-form
Adding React Form Controller
First of all we need to import useForm
and Controller
from react-hook-form
.
import { useForm, Controller } from "react-hook-form";
useForm
is the hook which handles all the functions related to the forms like field validation, errors, form submit etc.
Controller
wraps the fields to make them compatible to use with the library.
After importing, we can use the hook in our component. There are three properties of our interest – control
, handleSubmit
, errors
.
const { control, handleSubmit, errors } = useForm();
control
helps in giving control to our Controller. It indicates that all the fields belongs to the same form.
handleSubmit
is the wrapper for onSubmit
function. To use this library, submit should be passed through handleSubmit
.
errors
holds all the errors associated with the field.
Using Forms Controller on React Native text input
Controller
is the component which takes TextInput
(or any custom component) as a prop and render them with customized options. Check out the code –
<Controller
control={control}
render={({ onChange, onBlur, value }) => (
<TextInput
style={styles.input}
onBlur={onBlur}
onChangeText={value => onChange(value)}
value={value}
/>
)}
name="firstName"
rules={{ required: true }}
defaultValue=""
/>
There are various params of Controller. Let’s look at them –
control
– This indicates which method is going to control the functionality. We provide the parameter from our useForm hook.render
– In this prop we pass the component which needs to be rendered on screen. Here we are usingTextInput
. For different operations on text input, we will use the functions provided by Controller only like onChange, onBlur, value etc.name
– We are not creating separate state variables for different fields. A single hook will take care of all the fields in the form. We use the name prop to identify particular field.rules
– We define validation properties in this prop like – if the field is required, what should be the maximum and minimum length, type of field etc.defaultValue
– If you want to provide any pre filled value.
Displaying Errors of the Form Fields
It is simple to display errors in react-hook-form. The errors
property of useForm
holds the errors associated with all the fields of the form through which our controller is connected.
To access the errors of a particular field, we use the value of name
prop of the Controller component. For example –
{errors.firstName && <Text>First Name is required.</Text>}
If there are multiple types of errors like minLength
not met or exceeding the maximum length or not matching the password pattern, then we can use “type” property. For example –
{errors.firstName?.type === "required" &&
"First Name is required"}
{errors.firstName?.type === "maxLength" &&
"First Name exceed maximum length"}
But these will only work when required
and maxLength
are defined in the rules prop of the Controller.
Final submission of form
To submit a form, we need to call the handleSubmit function provided by useForm()
in the onPress
of button. We also have to pass our method which will handle the submitted form values in handleSubmit
as parameter. Check this code –
<Button title="Submit" onPress={handleSubmit(
(data) => { console.log(data) }
)} />
Now, when the button is pressed, handleSubmit
will be called. It will validate all the fields. If everything is without errors then passed method will be called with the form values.
We can make a server api call and send the values to the backend.
Complete Code & Working Demo
import React from "react";
import { Text, View, TextInput, Button } from "react-native";
import { useForm, Controller } from "react-hook-form";
export default function App() {
const { control, handleSubmit, errors } = useForm();
return (
<View>
<Controller
control={control}
render={({ onChange, onBlur, value }) => (
<TextInput
style={{paddingHorizontal: 20, borderWidth: 1, paddingVertical: 8}}
onBlur={onBlur}
onChangeText={value => onChange(value)}
value={value}
/>
)}
name="firstName"
rules={{ required: true }}
defaultValue=""
/>
{errors.firstName && <Text>First Name is required.</Text>}
<Controller
control={control}
render={({ onChange, onBlur, value }) => (
<TextInput
style={{paddingHorizontal: 20, borderWidth: 1, paddingVertical: 8}}
onBlur={onBlur}
onChangeText={value => onChange(value)}
value={value}
/>
)}
name="lastName"
rules={{ required: true, minLength: 8}}
defaultValue=""
/>
{errors.lastName?.type === "required" && <Text>Last Name is required.</Text>}
{errors.lastName?.type === "minLength" && <Text>Minimum 8 characters are required</Text>}
<Button title="Submit" onPress={handleSubmit((data) => console.log(data))} />
</View>
);
}
Live Demo
Conclusion
In this article we learned how to use react-hook-form to create forms in react native application. We can use the same principles to create forms in reactjs apps too.