React Hook Form & Material UI example with Form Validation

In this tutorial, I will show you how to implement React Hook Form Validation and Submit example using react-hook-form v7 and Material UI.


More Practice:
React Hooks: JWT Authentication (without Redux) example
React Hooks + Redux: JWT Authentication example
– Bootstrap instead: React Hook Form Validation example with Bootstrap

Related Posts:
Material UI File Upload example with Axios & Progress Bar
React Material UI examples with a CRUD Application
React Hooks File Upload example with Axios & Progress Bar
React Table example: CRUD App | react-table 7

Serverless with Firebase:
React Hooks + Firebase Realtime Database: CRUD App
React Hooks + Firestore example: CRUD app

React Hook Form & Material UI Validation Overview

We will implement validation for a React Form using React Hook Form v7 and Material UI. The form has:

  • Full Name: required
  • Username: required, from 6 to 20 characters
  • Email: required, email format
  • Password: required, from 6 to 40 characters
  • Confirm Password: required, same as Password
  • Accept Terms Checkbox: required

react-hook-form-material-ui-validation-example

When user makes some fields wrong:

react-hook-form-material-ui-validation-example-submit-error

This is a Successful Submission:

react-hook-form-material-ui-validation-example-submit

Technology

We’re gonna use following modules:

  • react 17/16
  • material-ui 4.11.4
  • react-hook-form 7
  • yup
  • @hookform/resolvers 2.6.0

Setup Project

First we need to install necessary modules.

Install React Hook Form

Open your project root folder, run the command:

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

Import Material UI to React App

Run command: npm install @material-ui/core
Or: yarn add @material-ui/core

Open package.json, the dependencies will look like this:

{
  "name": "react-hook-form-material-ui",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@babel/runtime": "^7.14.6",
    "@hookform/resolvers": "2.6.0",
    "@material-ui/core": "4.11.4",
    "@types/react": "17.0.11",
    "react": "17.0.2",
    "react-dom": "17.0.2",
    "react-hook-form": "7.9.0",
    "yup": "0.32.9"
  },
  ...
}

Form Validation with React Hook Form 7

The app component contains Form Validation example built with the React Hook Form v7 library.

Open src/App.js, we’re gonna import necessary library first:

import React, { Fragment } from 'react';
import { useForm, Controller } from 'react-hook-form';
import { yupResolver } from '@hookform/resolvers/yup';
import * as Yup from 'yup';

Next we use Yup schema validation library for Form validation rules:

const App = () => {
  const validationSchema = Yup.object().shape({
    fullname: Yup.string().required('Fullname is required'),
    username: Yup.string()
      .required('Username is required')
      .min(6, 'Username must be at least 6 characters')
      .max(20, 'Username must not exceed 20 characters'),
    email: Yup.string()
      .required('Email is required')
      .email('Email is invalid'),
    password: Yup.string()
      .required('Password is required')
      .min(6, 'Password must be at least 6 characters')
      .max(40, 'Password must not exceed 40 characters'),
    confirmPassword: Yup.string()
      .required('Confirm Password is required')
      .oneOf([Yup.ref('password'), null], 'Confirm Password does not match'),
    acceptTerms: Yup.bool().oneOf([true], 'Accept Terms is required')
  });
  ...
}

Then we pass the rules to the React Hook Form useForm() function using yupResolver() function from react-hook-form/resolvers library.

const App = () => {
  const validationSchema = ...

  const {
    register,
    control,
    handleSubmit,
    formState: { errors }
  } = useForm({
    resolver: yupResolver(validationSchema)
  });
  ...
}

The useForm() hook function returns an object that we use following methods:

The object also has formState that contains errors.

When the form is valid and submitted, onSubmit() method is called and the form data will show in console:

function App() {
  ...
  const onSubmit = data => {
    console.log(JSON.stringify(data, null, 2));
  };
  ...
}

React Hook Form with Material UI Validation template

Now we create the form with input fields and validation messages. We register form fields with the React Hook Form by calling the register function above with the field name of input element {...register('fieldname')}.

import {
  Paper,
  Box,
  Grid,
  TextField,
  Typography,
  FormControlLabel,
  Checkbox,
  Button
} from '@material-ui/core';

const App = () => {
  ...
  return (
    <Fragment>
      <Paper>
        <Box px={3} py={2}>
          <Typography variant="h6" align="center" margin="dense">
            React Hook Form - Material UI - Validation
          </Typography>

          <Grid container spacing={1}>
            <Grid item xs={12} sm={12}>
              <TextField
                required
                id="fullname"
                name="fullname"
                label="Full Name"
                fullWidth
                margin="dense"
                {...register('fullname')}
                error={errors.fullname ? true : false}
              />
              <Typography variant="inherit" color="textSecondary">
                {errors.fullname?.message}
              </Typography>
            </Grid>
            <Grid item xs={12} sm={6}>
              <TextField
                required
                id="username"
                name="username"
                label="Username"
                fullWidth
                margin="dense"
                {...register('username')}
                error={errors.username ? true : false}
              />
              <Typography variant="inherit" color="textSecondary">
                {errors.username?.message}
              </Typography>
            </Grid>
            <Grid item xs={12} sm={6}>
              <TextField
                required
                id="email"
                name="email"
                label="Email"
                fullWidth
                margin="dense"
                {...register('email')}
                error={errors.email ? true : false}
              />
              <Typography variant="inherit" color="textSecondary">
                {errors.email?.message}
              </Typography>
            </Grid>
            <Grid item xs={12} sm={6}>
              <TextField
                required
                id="password"
                name="password"
                label="Password"
                type="password"
                fullWidth
                margin="dense"
                {...register('password')}
                error={errors.password ? true : false}
              />
              <Typography variant="inherit" color="textSecondary">
                {errors.password?.message}
              </Typography>
            </Grid>
            <Grid item xs={12} sm={6}>
              <TextField
                required
                id="confirmPassword"
                name="confirmPassword"
                label="Confirm Password"
                type="password"
                fullWidth
                margin="dense"
                {...register('confirmPassword')}
                error={errors.confirmPassword ? true : false}
              />
              <Typography variant="inherit" color="textSecondary">
                {errors.confirmPassword?.message}
              </Typography>
            </Grid>
            <Grid item xs={12}>
              <FormControlLabel
                control={
                  <Controller
                    control={control}
                    name="acceptTerms"
                    defaultValue="false"
                    inputRef={register()}
                    render={({ field: { onChange } }) => (
                      <Checkbox
                        color="primary"
                        onChange={e => onChange(e.target.checked)}
                      />
                    )}
                  />
                }
                label={
                  <Typography color={errors.acceptTerms ? 'error' : 'inherit'}>
                    I have read and agree to the Terms *
                  </Typography>
                }
              />
              <br />
              <Typography variant="inherit" color="textSecondary">
                {errors.acceptTerms
                  ? '(' + errors.acceptTerms.message + ')'
                  : ''}
              </Typography>
            </Grid>
          </Grid>

          <Box mt={3}>
            <Button
              variant="contained"
              color="primary"
              onClick={handleSubmit(onSubmit)}
            >
              Register
            </Button>
          </Box>
        </Box>
      </Paper>
    </Fragment>
  );
};

export default App;

Run React Hook Form – Material UI Validation App

You can run our App with command: npm start.
If the process is successful, open Browser with Url: http://localhost:3000/ and check it.

Or run on Stackblitz:

Conclusion

Today we’ve built a React Hook Form v7 & Material UI example with Validation successfully.

If you want to use Bootstrap instead, please visit:
React Hook Form Validation example with Bootstrap

You can also use the Form Validation in following posts:
React Hooks CRUD example with Axios and Web API
React Hooks: JWT Authentication (without Redux) example
React Hooks + Redux: JWT Authentication example

More Practice:
React Pagination using Hooks example
React Hooks File Upload example with Axios & Progress Bar
React Table example: CRUD App | react-table 7

Serverless with Firebase:
React Hooks + Firebase Realtime Database: CRUD App
React Hooks + Firestore example: CRUD app

Fullstack:
React + Spring Boot + MySQL: CRUD example
React + Spring Boot + PostgreSQL: CRUD example
React + Spring Boot + MongoDB: CRUD example
React + Node.js + Express + MySQL: CRUD example
React + Node.js + Express + PostgreSQL example
React Redux + Node.js + Express + MySQL: CRUD example
React + Node.js + Express + MongoDB example
React + Django + Rest Framework example

4 thoughts to “React Hook Form & Material UI example with Form Validation”

Leave a Reply

Your email address will not be published. Required fields are marked *