How to use React Hook Form with Material UI

React Hook Form recently won the Productity Booster Award at React Summit so if you are not familiar with React Hook Form, now is a good time to learn it. React Hook Form is performant, has great docs and it works everywhere (including React Native).

Material UI continues to be the most popular open source React component library out there.

So if you are a React developer, there is a good chance you will find yourself with the opportunity to use Material UI's form components with React Hook Form.

A basic TextField

If you are working with forms in Material UI, you are most likely working with the TextField component like this one:

Enter your name

Example
import { TextField } from '@material-ui/core';

const BasicTextField = () => {
  return <TextField id="name" helperText="A basic TextField component" />;
};

export default BasicTextField;

Add React Hook Form

If you follow the React Hook Form docs, you will see code that looks like this:

<input name="example" ref={register} />

This doesn't quite work out of the box with Material UI's TextField component. Instead, we need to make use of the inputRef prop on TextField as demonstrated in this example.

Enter your name and press [Enter]

Example
import { useState } from 'react';
import { TextField } from '@material-ui/core';
import { useForm } from 'react-hook-form';

interface Inputs {
  name: string;
}

const HookedTextField = () => {
  const [name, setName] = useState<string>();
  const { register, handleSubmit } = useForm<Inputs>();

  const onSubmit = async (data: Inputs) => {
    setName(data.name);
  };

  return (
    <>
      <form onSubmit={handleSubmit(onSubmit)}>
        <TextField inputRef={register} id="name" name="name" helperText="Enter your name and press [Enter]" />
      </form>
      {name && <div>Submitted: {name}</div>}
    </>
  );
};

export default HookedTextField;

Reset the form

Sometimes you need to manually reset form state. React Hook Form makes this easy.

const { register, handleSubmit, reset } = useForm<Inputs>();

const onSubmit = async (data: Inputs) => {
  setName(data.name);
  reset();
};

Watch fields

React Hook Form also provides the watch function that allows you to immediately respond to changes in form state.

const { register, handleSubmit, watch } = useForm<Inputs>();

// This field will update as the user types
const currentName = watch('name');

Putting it all together

Enter your name and press [Enter]

Example
import { useState } from 'react';
import { TextField } from '@material-ui/core';
import { useForm } from 'react-hook-form';

interface Inputs {
  name: string;
}

const FinalTextField = () => {
  const [name, setName] = useState<string>();
  const { register, handleSubmit, reset, watch } = useForm<Inputs>();

  const currentName = watch('name');

  const onSubmit = async (data: Inputs) => {
    setName(data.name);
    reset();
  };

  return (
    <>
      <form onSubmit={handleSubmit(onSubmit)}>
        <TextField inputRef={register} id="name" name="name" helperText="Enter your name and press [Enter]" />
      </form>
      <div>
        {currentName && <div>Current: {currentName}</div>}
        {name && <div>Submitted: {name}</div>}
      </div>
    </>
  );
};

export default FinalTextField;

React Hook Form provides several other options for form management. When paired with Material UI, constructing forms doesn't get much easier.

Are you using React Hook Form with Material UI? Let me know on Twitter.

Join the Newsletter

I write about software development of all kinds (mostly front-end).

I won't send you spam. Unsubscribe at any time.