Hi everyone, I am going to explain how you can handle form data using react-hook-form.
I will cover integration of some material-ui elements which are:
- TextField
- Checkbox
- Radio Buttons
- Select
- Slider
These are the elements I use most often when working with forms.
These are the steps which I follow to handle form data hassle free.
import
import { useForm, Controller } from 'react-hook-form'
Initialize default values for your form
const { register, handleSubmit, watch, controller } = useForm({ defaultValues: { firstName: '', lastName: '', gender: 'female', country: 'India', languagesKnown: [], currentlyWorking: true, perHourRate: 50 } })
I always provide default values to the form, if not provided you will receive an error saying 'A component is changing an uncontrolled input to be controlled '.
Initialize the watchFields variable so that you can get updates when the state of each element is changed and run some other logic based on state change.
const watchFields = watch()
Register your elements
<TextField fullWidth type='text' label='First Name' {...register('firstName')} />
Full code for the form.
Github Link .
import { Container, Grid, TextField, Button, FormLabel, Checkbox, FormControl, FormGroup, FormControlLabel, RadioGroup, Radio, Select, MenuItem, Switch, Slider } from '@mui/material'
import { useForm, Controller } from 'react-hook-form'
export default function Home() {
const programmingLanguages = [
{ id: 1, name: 'Javascript' },
{ id: 2, name: 'Java' },
{ id: 3, name: 'Python' }
]
const countries = [
{ id: 1, name: 'India' },
{ id: 2, name: 'USA' },
{ id: 3, name: 'Canada' }
]
const { register, handleSubmit, watch, control } = useForm({
defaultValues: {
firstName: '',
lastName: '',
gender: 'female',
country: 'India',
languagesKnown: [],
currentlyWorking: true,
perHourRate: 50
}
})
const watchFields = watch()
const submit = (data) => {
console.log({ data })
}
return (
<Container>
<form onSubmit={handleSubmit(submit)}>
<Grid container spacing={2} sx={{ marginTop: '10px' }}>
<Grid item xs={6}>
<TextField
fullWidth
type='text'
label='First Name'
{...register('firstName')}
/>
</Grid>
<Grid item xs={6}>
<TextField
fullWidth
type='text'
label='Last Name'
{...register('lastName')}
/>
</Grid>
<Grid item xs={6}>
<FormLabel>Programming languages known</FormLabel>
<br />
{
programmingLanguages.map(language => <FormControlLabel key={language.id}
control={<Checkbox
value={language.name}
{...register('languagesKnown')} />}
label={language.name} />)
}
</Grid>
</Grid>
<Grid item xs={6}>
<FormControl component="fieldset">
<FormLabel component="legend">Gender</FormLabel>
<Controller
control={control}
name='gender'
render={({ field }) => <RadioGroup
{...field}
>
<FormControlLabel value="female" key='1' control={<Radio />} label="Female" />
<FormControlLabel value="male" key='2' control={<Radio />} label="Male" />
<FormControlLabel value="other" key='3' control={<Radio />} label="Other" />
</RadioGroup>}
/>
</FormControl>
</Grid>
<Grid item xs={6}>
<FormLabel>Please select your country</FormLabel>
<Controller
name='country'
control={control}
render={({ field }) => <Select
fullWidth
defaultValue='India'
{...field}
>
{countries.map(country => <MenuItem key={country.id} value={country.name}>{country.name}</MenuItem>)}
</Select>}
/>
</Grid>
<Grid>
<FormControlLabel control={<Switch defaultChecked {...register('currentlyWorking')} />} label="Currently working" />
</Grid>
<Grid item xs={6}>
<FormLabel>Please select your per hour rate</FormLabel>
<Controller
name='perHourRate'
control={control}
render={({ field }) => <Slider {...field} aria-label="Default" valueLabelDisplay="auto" />}
/>
<FormLabel>${watchFields.perHourRate}</FormLabel>
</Grid>
<Button type='submit'>Submit</Button>
</form>
</Container>
)
}