mui-react-hook-form-plus
mui-react-hook-form-plus copied to clipboard
The complete type-safe material-ui and react-hook-form combo and beyond with simple api.
The perfect recipe with material-ui๐TS๐react-hook-form & more...
The complete type-safe material-ui and react-hook-form combo and beyond with simple api.
Highly Customizable and supports 99% use-cases
Click here to see a live example!
Before Installing we need to install material-ui & react-hook-form
For date pickers
npm install @mui/x-date-pickers
---- or ----
yarn add @mui/x-date-pickers
Then Install
npm install mui-react-hook-form-plus
---- or ----
yarn add mui-react-hook-form-plus
If you are familiar with react-hook-form you will love it! Otherwise, you will also love it ๐ป
We use propGetter pattern just like react-hook-form is doing by registering the state of each field.
How to use it
- Import
ComponentsandHooksformmui-react-hook-form-plus. - From
useHookFormget theregisterStatemethod. - Call the
registerStatemethod withnameasargumentthat you want toregisterthefieldto withspread operator.
For more clear-cut answer follow the example below:
import { HookTextField, HookRating, useHookForm } from 'mui-react-hook-form-plus ';
const Component = () => {
const defaultValues = { name: 'Adiat Hasan', rating: 4 };
const { registerState, handleSubmit } = useHookForm({
defaultValues,
});
const onSubmit = (data: typeof defaultValues) => {
// will run if it is valid
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<HookTextField {...registerState('name')} />
<HookRating {...registerState('rating')} />
<button type='submit'>Submit</button>
</form>
);
};
We have awesome typescript support so that you can take the most of it. Also, validation is a piece of ๐ง(cake)
Validation
Add rules prop to your [InputComponents]
import { HookTextField, useHookForm } from 'mui-react-hook-form-plus ';
const Component = () => {
const defaultValues = { name: '', isAdmin: true };
const { registerState, handleSubmit } = useHookForm({
defaultValues,
});
const onSubmit = (data: typeof defaultValues) => {
// will run if it is validated | if !valid will thrown error in the UI
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<HookTextField
{...registerState('name')}
rules={{
required: {
value: true,
message: 'A required field',
},
// maxLength
// minLength
// pattern
// validate -> Fn -> reutrn -> srting | undefined
}}
/>
<button type='submit'>Submit</button>
</form>
);
};
It will validate based on validation rules we specify.
The onSubmit Fn will be triggered if all input === valid
For more options for rules look into this
Now what if we want our vanilla <input />?
Just use the register method not the registerState
import { HookTextField, useHookForm } from 'mui-react-hook-form-plus ';
const Component = () => {
const defaultValues = { name: 'Adiat Hasan', rating: 4 };
const { registerState, handleSubmit, register } = useHookForm({
defaultValues,
});
const onSubmit = (data: typeof defaultValues) => {
// -> do something with the data
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register('rating')} />
<HookTextField {...registerState('name')} />
<button type='submit'>Submit</button>
</form>
);
};
You might be wondering what about deep nested complex Component?
Use the FormContext to make it simple.
- Wrap your form with
HookFormProvider - Pass the methods returned from
useHookFormtoHookFormProvider - Get the
registerStatemethod anywhere in thetreefromuseHookFormContext
Example for Nested Component
import { HookTextField, useHookForm, HookFormProvider } from 'mui-react-hook-form-plus ';
const Component = () => {
const defaultValues = { firstName: '', lastName: '', sex: '', rating: 3.5 };
const methods = useHookForm<Person>({
defaultValues,
});
const { registerState, handleSubmit } = methods;
const onSubmit = (data: Person) => {
// do something
};
return (
<HookFormProvider {...methods}>
<form onSubmit={handleSubmit(onSubmit)}>
<HookTextField {...registerState('firstName')} textFieldProps={{ label: 'First Name' }} />
<HookTextField {...registerState('lastName')} textFieldProps={{ label: 'Last Name' }} />
<NestedComponent />
<button type='submit'>Submit</button>
</form>
</HookFormProvider>
);
};
Now we can get the registerState without prop drilling
import { HookRating, useHookForm } from 'mui-react-hook-form-plus ';
const NestedComponent = () => {
const { registerState } = useHookFormContext<Person>();
return <HookRating {...registerState('rating')} ratingProps={{ precision: 0.5 }} />;
};
Note that using FormContext can lack in performance as it is built on top of React.Context.
To optimize it further and for learning more check out this
Layouts [ Form + Grid ]
We baked in <Grid/> directly into the [InputComponents] so that it enhances the DX.
A gridProps is what you need to lay out the [InputComponents].
But don't forget to Wrap it inside a <Grid Container/>
import { Button, Grid } from '@mui/material';
import { HookTextField, HookRating, useHookForm } from 'mui-react-hook-form-plus ';
const Component = () => {
const defaultValues = { name: '', rating: 4 };
const { registerState, handleSubmit } = useHookForm({
defaultValues,
});
const onSubmit = (data: typeof defaultValues) => {
// will run if it is valid
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<Grid container spacing={3}>
<HookTextField
{...registerState('name')}
gridProps={{
xs: 12,
md: 5,
}}
/>
<HookRating
{...registerState('rating')}
gridProps={{
xs: 12,
md: 5,
}}
/>
<Grid>
<Button type='submit' variant='contained'>
Submit
</Button>
</Grid>
</Grid>
</form>
);
};
DatePicker
Package installation:
You need to install 3 different types of package to make the pickers work:
- The component (@mui/x-date-pickers) manages the rendering.
- The date-library (moment, dayjs, ...) manages the date manipulation.
- The adapter (@date-io) exposes your favorite date-library under a unified api used by component. First you have to install the date-library you want to use to manage dates, and the component package:
// Install component (community version)
yarn add @mui/x-date-pickers
// Install date library (if not already installed)
yarn add date-fns
import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
import { HookDatePicker } from 'mui-react-hook-form-plus ';
const Component = () => {
return (
<LocalizationProvider dateAdapter={AdapterDateFns}>
<form onSubmit={handleSubmit(onSubmit)}>
<HookDatePicker {...registerState('trialEndsAt')} />
</form>
</LocalizationProvider>
);
};
Available Input Components
<HookToggleButtonGroup /><HookAutoComplete /><HookRadioButton /><HookTextField /><HookCheckBox /><HookSelect /><HookSwitch /><HookRating /><HookSlider />
Check out Inputs Demo
DatePicker
<HookDatePicker /><HookStaticDatePicker /><HookDesktopDatePicker /><HookMobileDatePicker />
Check out DatePicker Demo
DateTimePicker
<HookDateTimePicker /><HookStaticDateTimePicker /><HookDesktopDateTimePicker /><HookMobileDateTimePicker />
Check out DateTimePicker Demo
TimePicker
<HookTimePicker /><HookStaticTimePicker /><HookDesktopTimePicker /><HookMobileTimePicker />
Check out TimePicker Demo
Form Hooks
useHookFormuseHookFormContext
Context Providers
HookFormProvider
Effortless Hooks
As we have promised with the project name with adding a -plus to mui-react-hook-form-plus.
We delivered it. A few effortless hooks to make your mui journey special.
We provided the same pattern as register and propGetters as the form components
Those Hooks are:
useMenuusePaginationuseAccordionuseTabsuseDialoguseBackdropuseBottomNavigation
And more hooks are in lab ๐งช preparing to be released. So, stay tuned.
Check out Hooks Demo
See examples
https://mui-react-hook-form-plus.vercel.app/?path=/docs/
MORE IS COMING...
Open for contributions
Just follow the CONTRIBUTING.md & you are good to go.

