MDB React & React Hook Form intergration

MDB React & React Hook Form intergration

MDB React integration with React Hook Form. Configuration, various examples of implementation and much more.

RHF is a library that makes dealing with forms in React easy. It is built with performance in mind. It allows you to create forms with minimal code and it is easy to integrate with MDB React.

In this tutorial you will learn how to validate forms created with MDB React using RHF.


Install React Hook Form

To install RHF, run the following command in your project directory:

You can find more details in the official documentation.

        
            
  npm i react-hook-form
  
        
    
        
            
  yarn add react-hook-form
  
        
    

Basic example

In this form we will use the useForm hook to register inputs and handleSubmit to console log the form data. The function will not be called if a required field is empty.

        
            
    import { useForm } from 'react-hook-form';
    import { MDBInput, MDBSelect, MDBBtn } from 'mdb-react-ui-kit';
    import { selectData } from './selectData';

    export default function App() {
      const { register, handleSubmit, setValue } = useForm();
      const onSubmit = (data) => console.log(data);

      return (
        <form onSubmit={handleSubmit(onSubmit)}>
          <MDBInput {...register('firstName', { required: true })} />
          <MDBSelect
            className='my-3'
            label='Gender'
            preventFirstSelection
            data={selectData}
            {...register('gender')}
            onChange={(opt) => setValue('gender', opt.value)}
          />
          <MDBBtn type='submit'>Submit</MDBBtn>
        </form>
      );
    }
  
        
    
        
            
    const selectData = [
      {
        text: 'male',
        value: 'male',
      },
      {
        text: 'female',
        value: 'female',
      },
      {
        text: 'other',
        value: 'other',
      },
    ];

    export { selectData };
  
        
    

Default values

If the component you use has a value set by default, don't forget to pass it to the useForm hook.

        
            
    import { useForm } from 'react-hook-form';
    import { MDBInput, MDBSelect, MDBBtn } from 'mdb-react-ui-kit';
    import { selectData } from './selectData';

    export default function App() {
      const { register, handleSubmit, setValue } = useForm({
        defaultValues: {
          gender: 'male',
        },
      });
      const onSubmit = (data) => console.log(data);

      return (
        <form onSubmit={handleSubmit(onSubmit)}>
          <MDBSelect
            label='Gender'
            data={selectData}
            {...register('gender')}
            onChange={(opt) => setValue('gender', opt.value)}
          />
          <MDBBtn type='submit'>Submit</MDBBtn>
        </form>
      );
    }
  
        
    
        
            
    const selectData = [
      {
        text: 'male',
        value: 'male',
      },
      {
        text: 'female',
        value: 'female',
      },
      {
        text: 'other',
        value: 'other',
      },
    ];

    export { selectData };

  
        
    

Basic validation

register accepts an object as its second argument, which includes validation rules. There are many options available, but the most commonly used are:

  • required - field is required
  • minLength - minimum length
  • maxLength - maximum length
  • min - minimum value
  • max - maximum value
  • pattern - regex pattern
  • validate - custom function

The options can be passed with or without an error message.

        
            
    <MDBInput
    {...register("MDBInput", {
      minLength: 5
    })}
    />
  
        
    
        
            
    <MDBInput
    {...register("MDBInput", {
      minLength: {
        value: 5,
        message: "The text must be at least 5 characters long",
      }
    })}
  />
  
        
    

Copy the code from this snippet below to see how it works in practice. Open console and see how the error object changes.

        
            
    import { useForm } from 'react-hook-form';
    import { MDBInput, MDBBtn, MDBDatepicker } from 'mdb-react-ui-kit';
    import { selectData } from './selectData';

    export default function App() {
      const {
        register,
        handleSubmit,
        setValue,
        formState: { errors },
      } = useForm();

      console.log('errors', errors);
      const onSubmit = (data) => console.log(data);

      return (
        <form onSubmit={handleSubmit(onSubmit)}>
          <MDBInput
            className='my-3'
            label='First name'
            {...register('firstName', {
              required: true,
              minLength: 2,
              maxLength: 10,
            })}
          />
          <MDBInput
            className='my-3'
            label='Last name'
            {...register('lastName', {
              required: true,
              minLength: 2,
              maxLength: 10,
            })}
          />
          <MDBDatepicker
            className='my-3'
            label='Date of visit'
            {...register('date', {
              required: true,
              pattern: /^(0[1-9]|[12][0-9]|3[01])\/(0[1-9]|1[0-2])\/\d{4}$/,
            })}
            onChange={(value) => setValue('date', value)}
          />
          <MDBBtn type='submit'>Submit</MDBBtn>
        </form>
      );
    }
  
        
    
        
            
    import { useForm } from 'react-hook-form';
    import { MDBInput, MDBBtn, MDBDatepicker } from 'mdb-react-ui-kit';

    export default function App() {
      const {
        register,
        handleSubmit,
        setValue,
        formState: { errors },
      } = useForm();

      console.log('errors', errors);
      const onSubmit = (data) => console.log(data);

      return (
        <form onSubmit={handleSubmit(onSubmit)}>
          <MDBInput
            className='my-3'
            label='First name'
            {...register('firstName', {
              required: 'This field is required.',
              minLength: {
                value: 2,
                message: 'First name should be at least 2 characters long.',
              },
              maxLength: {
                value: 10,
                message: 'First name should be at most 10 characters long.',
              },
            })}
          ></MDBInput>
          <MDBInput
            className='my-3'
            label='Last name'
            {...register('lastName', {
              required: 'This field is required.',
              minLength: {
                value: 2,
                message: 'Last name should be at least 2 characters long.',
              },
              maxLength: {
                value: 10,
                message: 'Last name should be at most 10 characters long.',
              },
            })}
          ></MDBInput>
          <MDBDatepicker
            className='my-3'
            label='Date of visit'
            {...register('date', {
              required: 'This field is required.',
              pattern: {
                value: /^(0[1-9]|[12][0-9]|3[01])\/(0[1-9]|1[0-2])\/\d{4}$/,
                message: 'Date should be in format dd/mm/yyyy.',
              },
            })}
            onChange={(value) => setValue('date', value)}
          ></MDBDatepicker>
          <MDBBtn type='submit'>Submit</MDBBtn>
        </form>
      );
    }

  
        
    

Invalid feedback

We already have some validation rules and different error messages. Let's check out how to display them.

Check this example.

        
            
    import React from "react";
    import { useForm } from "react-hook-form";
    import { MDBInput, MDBBtn, MDBDatepicker } from "mdb-react-ui-kit";

    export default function App() {
      const {
        register,
        handleSubmit,
        setValue,
        formState: { errors },
      } = useForm();

      console.log("errors", errors);
      const onSubmit = (data) => console.log(data);

      return (
        <form onSubmit={handleSubmit(onSubmit)}>
          <div className="position-relative pb-3">
            <MDBInput
              className={`${errors.firstName ? "is-invalid" : ""}`}
              label="First name"
              {...register("firstName", {
                required: "This field is required.",
                minLength: {
                  value: 2,
                  message: "First name should be at least 2 characters long.",
                },
                maxLength: {
                  value: 10,
                  message: "First name should be at most 10 characters long.",
                },
              })}
            />
            {errors.firstName && (
              <span className="invalid-feedback d-block">{errors.firstName.message}</span>
            )}
          </div>
          <div className="position-relative pb-3">
            <MDBInput
              className={`${errors.lastName ? "is-invalid" : ""}`}
              label="Last name"
              {...register("lastName", {
                required: "This field is required.",
                minLength: {
                  value: 2,
                  message: "Last name should be at least 2 characters long.",
                },
                maxLength: {
                  value: 10,
                  message: "Last name should be at most 10 characters long.",
                },
              })}
            />
            {errors.lastName && (
              <span className="invalid-feedback d-block">{errors.lastName.message}</span>
            )}
          </div>
          <div className="position-relative pb-3">
            <MDBDatepicker
              className={`${errors.date ? "is-invalid" : ""}`}
              label="Date of visit"
              {...register("date", {
                required: "This field is required.",
                pattern: {
                  value: /^(0[1-9]|[12][0-9]|3[01])\/(0[1-9]|1[0-2])\/\d{4}$/,
                  message: "Date should be in format dd/mm/yyyy.",
                },
              })}
              onChange={(value) => setValue("date", value)}
            />
            {errors.date && <span className="invalid-feedback d-block">{errors.date.message}</span>}
          </div>
          <MDBBtn className="mt-4" type="submit">
            Submit
          </MDBBtn>
        </form>
      );
    }
  
        
    

Custom validation

Sometimes you may need to create a custom validation rule. You can do it by passing a function to the validate option.

        
            
    import React, { useState } from 'react';
    import { useForm } from 'react-hook-form';
    import { MDBSelect, MDBBtn } from 'mdb-react-ui-kit';
    import { selectData } from './selectData';

    function App() {
      const [wasValidated, setWasValidated] = useState(false);
      const {
        handleSubmit,
        register,
        setValue,
        setError,
        clearErrors,
        formState: { errors },
      } = useForm();

      console.log('errors', errors);

      const onSubmit = (data) => console.log(data);

      return (
        <div className='col-md-6 mx-auto'>
          <form onSubmit={handleSubmit(onSubmit)} className='row align-items-center'>
            <div className='my-2 col-6 position-relative'>
              <MDBSelect
                label='Select at least 3 options'
                inputClassName={`${errors.MDBSelect ? 'is-invalid' : ''}`}
                multiple
                required
                invalidFeedback='You must select at least 3 options'
                preventFirstSelection
                {...register('MDBSelect', {
                  validate: (options) => {
                    if (!options || options.length < 3) {
                      return 'You must select at least 3 options';
                    }
                  },
                })}
                onChange={(e) => {
                  clearErrors('MDBSelect');
                  setValue('MDBSelect', e);
                  if (!wasValidated) return;
                  if (!e || e.length < 3) {
                    return setError('MDBSelect', {
                      type: 'validate',
                      message: 'You must select at least 3 options',
                    });
                  }
                }}
                data={selectData}
              />
              {errors.MDBSelect &&
              <span className='invalid-feedback' style={{ display: 'block' }}>
                {errors.MDBSelect.message}
              </span>}
            </div>
            <MDBBtn onClick={() => setWasValidated(true)} type='submit'>
              Submit
            </MDBBtn>
          </form>
        </div>
      );
    }

    export default App;
  
        
    
        
            
    const selectData = [
      { text: 'Tony Stark', value: 'Ironman' },
      { text: 'Bruce Wayne', value: 'Batman' },
      { text: 'Clark Kent', value: 'Superman' },
      { text: 'Peter Parker', value: 'Spiderman' },
      { text: 'Steve Rogers', value: 'Captain America' },
    ];

    export { selectData };