How to use react-hook-form with ant design or material UI
react hook form author here. React Hook Form embrace uncontrolled components and native inputs, however it's hard to avoid working with external controlled component such as React-Select, AntD and Material-UI. So I have built a wrapper component to help you integrate easier.
https://github.com/react-hook-form/react-hook-form-input
Ok you may wonder what’s the point of doing this, and what are you gettin out from react hook form with controlled components? Firstly, you still benefit from our in build validation or schema validation at your choice. Secondary this will improve your app or form performance by isolating your input state update to itself, which means ur form root can be resulted with 0 re-render even with controlled component.
Here is codesandbox example: https://codesandbox.io/s/react-hook-form-hookforminput-rzu9s
Hopefully those make sense and that extra component Which I have created helps you too.
On top this, i have also built a wrapper component to make things a bit easier:
import React from 'react';
import useForm from 'react-hook-form';
import { RHFInput } from 'react-hook-form-input';
import Select from 'react-select';
const options = [
{ value: 'chocolate', label: 'Chocolate' },
{ value: 'strawberry', label: 'Strawberry' },
{ value: 'vanilla', label: 'Vanilla' },
];
function App() {
const { handleSubmit, register, setValue, reset } = useForm();
return (
<form onSubmit={handleSubmit(data => console.log(data))}>
<RHFInput
as={<Select options={options} />}
rules={{ required: true }}
name="reactSelect"
register={register}
setValue={setValue}
/>
<button
type="button"
onClick={() => {
reset({
reactSelect: '',
});
}}
>
Reset Form
</button>
<button>submit</button>
</form>
);
}
https://github.com/react-hook-form/react-hook-form-input
update
React-hook-form v4, react-hook-form-input has been merged into the main repo and renamed to Controller.
https://react-hook-form.com/api#Controller
For Material-UI you can pass register
through the TextField component prop inputRef
(I'm also using Yup for validation schemas)
import React, { useState } from 'react';
import { Button, TextField } from '@material-ui/core';
import useForm from 'react-hook-form';
import { object, string } from 'yup';
const Form: React.FC = () => {
const schema = object().shape({
username: string().required('Username is required'),
password: string().required('Password is required'),
});
const { register, handleSubmit, errors } = useForm({ validationSchema: schema });
const onSubmit = (data: any) => {
console.log(data);
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<TextField
name="username"
error={!!errors.username}
label="Username"
helperText={errors.username ? errors.username.message : ''}
type="email"
inputRef={register}
fullWidth
/>
<TextField
name="password"
error={!!errors.password}
label="Password"
inputRef={register}
helperText={errors.password ? errors.password.message : ''}
type="password"
fullWidth
/>
<Button
color="primary"
type="submit"
variant="contained"
fullWidth
>
Submit
</Button>
</form>
);
};
The latest advice for V4 is to use the built-in <Controller />
component (docs). You don't need to install the extra dependency of react-hook-form-input
.
From the README.md of react-hook-form-input:
This component is now a part of React Hook Form V4, and renamed to Controller with much simpler API.
Example:
<Controller
as={<TextField />}
name="firstName"
control={control}
defaultValue=""
/>
Note that the @Bill, the author of the accepted answer, now also says that the answer is outdated and to "please use controller instead."