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 –

  1. control – This indicates which method is going to control the functionality. We provide the parameter from our useForm hook.
  2. render – In this prop we pass the component which needs to be rendered on screen. Here we are using TextInput. For different operations on text input, we will use the functions provided by Controller only like onChange, onBlur, value etc.
  3. 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.
  4. 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.
  5. 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.