Skip to content

Instantly share code, notes, and snippets.

@rafabarbosa
Forked from pjchender/Form.tsx
Created May 24, 2022 20:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rafabarbosa/e26681581a59ac975cbb4af0a55a6938 to your computer and use it in GitHub Desktop.
Save rafabarbosa/e26681581a59ac975cbb4af0a55a6938 to your computer and use it in GitHub Desktop.
Nested Object Fields in React Hook Form
import { DevTool } from '@hookform/devtools';
import { yupResolver } from '@hookform/resolvers/yup';
import { Button, makeStyles, TextField } from '@material-ui/core';
import { Controller, SubmitHandler, useForm } from 'react-hook-form';
import * as yup from 'yup';
const useStyles = makeStyles(theme => ({
root: {
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
padding: theme.spacing(2),
'& .MuiTextField-root': {
margin: theme.spacing(1),
width: '300px',
},
'& .MuiButtonBase-root': {
margin: theme.spacing(2),
},
},
}));
const schema = yup.object().shape({
personalInfo: yup.object().shape({
username: yup.string().required(),
email: yup.string().required(),
}),
password: yup.string().min(6),
});
interface Inputs {
personalInfo: {
username: string;
email: string;
};
password: string;
}
interface Props {
onModalClose: () => void;
}
function Form({ onModalClose }: Props): JSX.Element {
const classes = useStyles();
const { handleSubmit, control, formState } = useForm<Inputs>({
mode: 'onBlur',
resolver: yupResolver(schema),
defaultValues: {
personalInfo: {
username: '',
email: '',
},
password: '',
},
});
const onSubmit: SubmitHandler<Inputs> = data => {
console.log('onSubmit', {
formState: {
...formState,
},
data,
});
return null;
};
return (
<>
<form className={classes.root} onSubmit={handleSubmit(onSubmit)}>
<Controller
name="personalInfo.username"
control={control}
render={({ field: { onChange, onBlur, value, ref } }) => (
<TextField
onBlur={onBlur}
onChange={onChange}
value={value}
type="text"
variant="filled"
placeholder="username"
ref={ref}
/>
)}
/>
<Controller
name="personalInfo.email"
control={control}
render={({ field: { onChange, onBlur, value, ref } }) => (
<TextField
onChange={onChange}
onBlur={onBlur}
value={value}
ref={ref}
type="email"
variant="filled"
placeholder="Email"
/>
)}
/>
<Controller
name="password"
control={control}
render={({ field: { onChange, onBlur, value, ref } }) => (
<TextField
type="password"
variant="filled"
placeholder="Password"
onChange={onChange}
onBlur={onBlur}
value={value}
ref={ref}
/>
)}
/>
<Button variant="contained" onClick={onModalClose}>
Cancel
</Button>
<Button variant="contained" type="submit" color="primary">
Submit
</Button>
</form>
{/*
Devtool currently not support nested object field, but it works correctly in react-hook-form
*/}
<DevTool control={control} placement="top-right" />
</>
);
}
export default Form;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment