React-hook-form is a handy, easy-to-use form library and simpler form validation.
Let’s learn how to use react-hook-form in a project.
Setting
With npm:
1 2 | npm i react-hook-form |
If using yarn:
1 2 | yarn add react-hook-form |
After the installation is complete, we create a user registration form with username, email, password to practice
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | import React from "react"; const styles = { container: { width: "80%", margin: "0 auto", }, input: { width: "100%", }, }; export default function Signup() { return ( <div style={styles.container}> <h4>Sign up</h4> <form> <input placeholder="Username" style={styles.input} /> <input placeholder="Email" style={styles.input} /> <input placeholder="Password" style={styles.input} /> <button type="submit">Submit</button> </form> </div> ); } |
How do I use the useForm hook?
To get started with react-hook-form we call useForm. We will use register
to get an object. register is a function that needs to be associated with each input by ref
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | function App() { const { register } = useForm(); return ( <div style={styles.container}> <h4>Signup</h4> <form> <input ref={register} placeholder="Username" style={styles.input} /> <input ref={register} placeholder="Email" style={styles.input} /> <input ref={register} placeholder="Password" style={styles.input} /> <button type="submit">Submit</button> </form> </div> ); } |
The register function will take the value that the user has entered in the input box to validate it. The register sends these values to a function when submitting the form.
For registers to work properly, for each input need to provide an appropriate name attribute, for example here, with input email we set name = “email”.
The reason for adding the name attribute à each time the form is submitted, we will get all input values on a single object, each property when sent back to the server side, will be named after this name. .
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | function App() { const { register } = useForm(); return ( <div style={styles.container}> <h4>My Form</h4> <form> <input name="username" ref={register} placeholder="Username" style={styles.input} /> <input name="email" ref={register} placeholder="Email" style={styles.input} /> <input name="password" ref={register} placeholder="Password" style={styles.input} /> <button type="submit">Submit</button> </form> </div> ); } |
How do I submit a form with handleSubmit?
To handle the submission of the form and receive input data, normally we use the onSubmit
of the form and call the processing function upon submission.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | function App() { const { register } = useForm(); function handleSubmitSignUp() {} return ( <div style={styles.container}> <h4>My Form</h4> <form onSubmit={handleSubmitSignUp}> <input name="username" ref={register} placeholder="Username" style={styles.input} /> <input name="email" ref={register} placeholder="Email" style={styles.input} /> <input name="password" ref={register} placeholder="Password" style={styles.input} /> <button type="submit">Submit</button> </form> </div> ); } |
=> With useForm, you call handleSubmit
function and call handleSubmitSignUp
nested inside as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | function App() { const { register, handleSubmit } = useForm(); function handleSubmitSignUp(data) { console.log(data); // { username: 'test', email: 'test', password: 'test' } } return ( <div style={styles.container}> <h4>Signup</h4> <form onSubmit={handleSubmit(handleSubmitSignUp)}> <input name="username" ref={register} placeholder="Username" style={styles.input} /> <input name="email" ref={register} placeholder="Email" style={styles.input} /> <input name="password" ref={register} placeholder="Password" style={styles.input} /> <button type="submit">Submit</button> </form> </div> ); } |
handleSubmit
will get all the input data and we will get in handleSubmitSignUp
with the data
object.
You can easily check the data when console.log(data)
at handleSubmitSignUp
.
Validation data input with register
To validate the form and add conditions to each input value is very simple, we just need to pass the condition in the register
function.
register
accepts an object, whose properties are conditions on the input. For example, we want the username field required to be entered, more than 6 characters and less than 24 characters:
1 2 3 4 5 6 7 8 9 10 11 12 | <input name="username" ref={register({ required: true, minLength: 6, maxLength: 20, pattern: /^[A-Za-z]+$/i, })} style={styles.input} placeholder="Username" /> |
The required: true
attribute means that data is required to input, and minLength: 6
more than 6 characters, maxLength: 20
is less than 20 characters, in case you want to apply regex, we use pattern, in the wallet This example allows only lower case letters or upper case letters.
Display errors and validation mode
In case of entering values that do not match the conditions, we will get object errors
from useForm.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | function App() { const { register, handleSubmit, errors } = useForm({ mode: "onBlur", }); function onSubmit(data) { console.log(data); } return ( <div style={styles.container}> <h4>My Form</h4> <form onSubmit={handleSubmit(onSubmit)}> <input name="username" ref={register({ required: true, minLength: 6, maxLength: 20, pattern: /^[A-Za-z]+$/i, })} style={{ ...styles.input, borderColor: errors.username && "red" }} placeholder="Username" /> <input name="email" ref={register({ required: true, validate: (input) => isEmail(input), })} style={{ ...styles.input, borderColor: errors.email && "red" }} placeholder="Email" /> <input name="password" ref={register({ required: true, minLength: 6, })} style={{ ...styles.input, borderColor: errors.password && "red" }} placeholder="Password" /> <button type="submit" disabled={formState.isSubmitting}> Submit </button> </form> </div> ); } |
By default, errors will be updated after submitting the form, but we can update errors in different modes:
mode: onChange | onBlur | onSubmit | onTouched | all = 'onSubmit'
onSubmit
(Default): Validation will trigger event submit.
onBlur
: Validation will trigger the event blur.
onChange
: Validation will trigger event change on each input and update errors multiple times when there is a value change, which also significantly affects performance.
onTouched
: Validation will trigger the event blur first, and then it will trigger with any event changes.
To set or clear errors, we use setError and clearError.
Applies to forms using external components
Some forms use external components such as React-Select, AntD and Material-UI, and using the outer controller will make it easier to work with. The structure is as follows:
Name | Type | Required | description |
---|---|---|---|
name | string | ✓ | Unique name input |
control | Object | control object set using useForm. Optional when using FormProvider. | |
rules | Object | Validation rules are similar to the register’s format: rules={{ required: true }} | |
render | Function | This is a render prop. This function returns the React element and supplies events and values to the component. Provide onChange, onBlur, name, ref, and value to the child component |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | import React from "react"; import { TextField } from "@material-ui/core"; import { useForm, Controller } from "react-hook-form"; function App() { const { handleSubmit, control } = useForm(); return ( <form onSubmit={handleSubmit(data => console.log(data))}> <Controller control={control} name="TextField" render={({ onChange, onBlur, value }) => ( <TextField onChange={onChange} onBlur={onBlur} selected={value} /> )} /> <input type="submit" /> </form> ); } |
Above is the post on creating form and validating with react-hook-form, hopefully it will help everyone when working with forms in React. The article is referenced from the article How to Build React Forms the Easy Way with react-hook-form author Reed Barger. You can also find out carefully at the homepage https://react-hook-form.com