I am having issues with React Hook Forms with Material UI Components and I can't really find resources on this. I have a page where I fetch the countries and the current profile information and I want to show it inside the form. Initially I want to set the country to Germany.
const [countries, setCountries] = useState([]);
const { control, handleSubmit, register, reset } = useForm();
const [currentProfile, setCurrentProfile] = useState<profiles.resProfileFields>();
useEffect(() => {
const getProfileData = async () => {
try {
const profile = await api.get(profiles.getById, { id: profileId });
if (profile != null && profile != undefined) {
setCurrentProfile(profile);
setcountryId(profile.country.id);
}
} catch (err) {
console.log(`error getting: ${err}`);
}
};
getProfileData();
getCountries();
}, [profileId]);
useEffect(() => {
reset(currentProfile);
}, [currentProfile]);
const getCountries = () => {
api
.get(routes.countries.list, {})
.then(res => {
setCountries(res);
})
.catch(err => { });
};
<form onSubmit={handleSubmit(onSubmit)}>
<TextField
inputRef={register}
name="name"
label="* Name"
InputLabelProps={{
shrink: true
}}
variant="outlined"
placeholder="Name"
className="form-item-full"
/>
<Controller
name="country"
as={
<Autocomplete
className="form-item"
options={countries}
getOptionLabel={option => option.name}
renderInput={params => (
<TextField
{...params}
inputRef={register}
label="Country"
placeholder="Select a Country"
InputLabelProps={{
shrink: true
}}
variant="outlined"
/>
)}
/>
}
defaultValue="Germany"
control={control}
/>
</form>
In the codesandbox suggested by Bill you can see an exact example.
The Controller
with the Autocomplete
component should look like this:
<Controller
render={props => (
<Autocomplete
{...props}
options={countries}
getOptionLabel={option => option.name}
renderInput={params => (
<TextField
{...params}
label="Country"
placeholder="Select a Country"
InputLabelProps={{
shrink: true
}}
variant="outlined"
/>
)}
onChange={(_, data) => props.onChange(data)}
/>
)}
name="country"
control={control}
/>
Because the selected country actually is an Object, you will have to set the German country object in the defaultValues
:
const { control, handleSubmit, register, reset } = useForm({
defaultValues: {
country: { name: 'Germany', id: 1234 },
}
});
If you don't want to 'hardcode' the country in the defaultValues
Object, you could move the getCountries
call up one level and pass it to the form. You can now conditionally render the form when all data is available and find the country in the countries list like so:
const MyForm = ({ countries }) => {
const { control, handleSubmit, register, reset } = useForm({
defaultValues: {
country: countries.find(({ name }) => name === 'Germany'),
}
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With