DEV Community

joedev090
joedev090

Posted on

Forms in react with react-hook-form

Hey Coders,

Long time ago...

Here we have a new article about how to add "superpowers" to your forms to add validations, errors and more.

As always we begin coding!!

1.- In your directory of your preference, open a terminal and run this code:

npm create vite@latest

2.- Remove existing code in App.jsx and add this code:

<h1>React Forms</h1> 
Enter fullscreen mode Exit fullscreen mode

Image description

Here we have a cleaned solution to implement our small project!!

3.- Create a directory in src called forms and create a form.jsx and form.css with these code:

form.jsx

import React from 'react'; import './form.css'; export default function Form() { return ( <div className="add-place"> <div className="form"> <form> <h1>Add Place</h1> <div className="form-field"> <label htmlFor="title">Title: </label> <input type="text" placeholder="Title" name="title" id="title" /> </div> <div className="form-field"> <label htmlFor="description">Description: </label> <input type="text" placeholder="Description" name="description" id="description" /> </div> <button type="submit">Add Place</button> </form> </div> </div> ); } 
Enter fullscreen mode Exit fullscreen mode

form.css

.add-place { display: flex; justify-content: center; align-items: center; height: 100vh; background-color: #1e1e1e; font-family: Arial, sans-serif; color: #e0e0e0; width: 100vw; } .form { background-color: #2c2c2c; padding: 2rem; border-radius: 8px; box-shadow: 0 0 15px rgba(0, 0, 0, 0.5); width: 100%; max-width: 400px; } .form h1 { margin-bottom: 1rem; font-size: 1.5rem; color: #f0f0f0; } .form-field { margin-bottom: 1.5rem; } .form-field label { display: block; margin-bottom: 0.5rem; font-weight: bold; color: #cccccc; } .form-field input { width: 100%; padding: 0.5rem; border: 1px solid #444; border-radius: 4px; background-color: #3a3a3a; color: #e0e0e0; font-size: 1rem; } .form-field input:focus { border-color: #6200ea; outline: none; } button[type="submit"] { width: 100%; padding: 0.75rem; border: none; border-radius: 4px; background-color: #6200ea; color: #fff; font-size: 1rem; cursor: pointer; transition: background-color 0.3s ease; } button[type="submit"]:hover { background-color: #3700b3; } .error { color: #FF6961; } 
Enter fullscreen mode Exit fullscreen mode

The result will be:

Image description

From this part, we have the something more interesting:

4.- Install react-hook-form, yup and resolver dependencies

npm install react-hook-form @hookform/resolvers yup

  1. Add the rest of the code to the form in react
  • Add the imports:
import { useForm } from 'react-hook-form'; import { yupResolver } from '@hookform/resolvers/yup'; import * as yup from 'yup'; 
Enter fullscreen mode Exit fullscreen mode
  • Add the schema with validations, the resolver with the useForm where we add the register, handleSubmit, formState: { errors }
const schema = yup.object().shape({ title: yup.string().required('Title is required'), description: yup.string().required('Description is required'), }); const { register, handleSubmit, formState: { errors } } = useForm({ resolver: yupResolver(schema), }); 
Enter fullscreen mode Exit fullscreen mode
  • The onSubmit function, where we can add the functionality after clicked in Save
const onSubmit = (data) => { console.log(data); }; 
Enter fullscreen mode Exit fullscreen mode
  • Finally, we add the {...register['title']} and the validation part in the html
<input type="text" placeholder="Title" name="title" id="title" {...register('title')} /> {errors.title && <p className="error">{errors.title.message}</p>} 
Enter fullscreen mode Exit fullscreen mode

We should add the same for the description input


Finally the final result in form.jsx is:

import React from 'react'; import { useForm } from 'react-hook-form'; import { yupResolver } from '@hookform/resolvers/yup'; import * as yup from 'yup'; import './form.css'; export default function Form() { const schema = yup.object().shape({ title: yup.string().required('Title is required'), description: yup.string().required('Description is required'), }); const { register, handleSubmit, formState: { errors } } = useForm({ resolver: yupResolver(schema), }); const onSubmit = (data) => { console.log(data); }; return ( <div className="add-place"> <div className="form"> <form onSubmit={handleSubmit(onSubmit)}> <h1>Add Place</h1> <div className="form-field"> <label htmlFor="title">Title: </label> <input type="text" placeholder="Title" name="title" id="title" {...register('title')} /> {errors.title && <p className="error">{errors.title.message}</p>} </div> <div className="form-field"> <label htmlFor="description">Description: </label> <input type="text" placeholder="Description" name="description" id="description" {...register('description')} /> {errors.description && <p className="error">{errors.description.message}</p>} </div> <button type="submit">Add Place</button> </form> </div> </div> ); } 
Enter fullscreen mode Exit fullscreen mode

And there you go!!

We have our form validated:

Image description

We try to save with no description, show the error message!

Let me know if you have some question or suggestion about this tutorial.

See you in the next episode!!! :)

Top comments (0)