Simple registration form with a full validation including checkbox field.
Working code example can be found on my github
Dependencies:
$ npx create-react-app react-checkbox-material --template typescript
$ npm install -S yup --save
$ npm install -D @types/yup --save
$ npm install @material-ui/core --save
$ npm install react-hook-form --save
$ npm install --save typescript @types/node @types/react @types/react-dom @types/jest
import * as yup from "yup";
const schema = yup.object().shape({
email: yup.string().email("Incorrect format").required("E-mail is required"),
password: yup
.string()
.required("Password is required")
.min(4, "​Password must be at least 4 characters"),
passwordConfirm: yup
.string()
.required("Passwords does not match")
.oneOf([yup.ref("password"), null], "Passwords must match"),
termsCheck: yup
.boolean()
.oneOf([true], "Required terms of use")
.required("Required terms of use"),
});
export default schema;
Initialize useForm with created schema in order to use it later in the RegisterForm component.
import { useForm } from "react-hook-form";
interface FormData {
email: string;
password: string;
passwordConfirm: string;
}
const Register = () => {
const { register, handleSubmit, errors, setError } = useForm({
validationSchema: registerSchema,
});
const submit = (data: FormData) => {
console.log(data);
// make an auth request and use setError to handle errors from there
};
return (
<RegisterForm
onSubmit={submit}
register={register}
formHandleSubmit={handleSubmit}
errors={errors}
/>
);
};
export default Register;
Each field needs to be register using inputRef in order to pass reference to the hook.
<TextField
id="email"
label="Email Address"
name="email"
autoComplete="email"
inputRef={register}
error={Boolean(errors.email)}
helperText={errors.email ? errors.email.message : " "}
/>
The situation with Checkbox is a little different since it is not getting parameters as TextField. To have it working we need to use component FormControlLabel:
import FormControlLabel from "@material-ui/core/FormControlLabel";
<FormControlLabel
control={
<Checkbox
id="termsCheck"
name="termsCheck"
color="primary"
required
/>
}
id="termsCheck"
name="termsCheck"
label={termsCheckboxLabel}
inputRef={register}
/>
<FormHelperText error>
{errors.termsCheck ? errors.termsCheck.message : " "}
</FormHelperText>
<form
className={classes.form}
onSubmit={formHandleSubmit(onSubmit)}
noValidate
>
// fields
</form>
import Button from "@material-ui/core/Button";
import Checkbox from "@material-ui/core/Checkbox";
import Container from "@material-ui/core/Container";
import FormControlLabel from "@material-ui/core/FormControlLabel";
import FormHelperText from "@material-ui/core/FormHelperText";
import Grid from "@material-ui/core/Grid";
import TextField from "@material-ui/core/TextField";
import Typography from "@material-ui/core/Typography";
import React from "react";
import { SignUpData } from "./interfaces";
import { useRegisterFormStyles } from "./styles";
export default function SignUp({
onSubmit,
formHandleSubmit,
register,
errors,
}: SignUpData) {
const classes = useRegisterFormStyles();
const termsCheckboxLabel = (
<div>
I accept <a href="/terms">terms of use</a>
</div>
);
return (
<Container component="main" maxWidth="xs">
<div className={classes.paper}>
<Typography component="h1" variant="h5">
Register
</Typography>
<form
className={classes.form}
onSubmit={formHandleSubmit(onSubmit)}
noValidate
>
<Grid container spacing={2}>
<Grid item xs={12}>
<TextField
variant="outlined"
required
fullWidth
id="email"
label="Email Address"
name="email"
autoComplete="email"
inputRef={register}
error={Boolean(errors.email)}
helperText={errors.email ? errors.email.message : " "}
/>
</Grid>
<Grid item xs={12}>
<TextField
variant="outlined"
required
fullWidth
name="password"
label="Password"
type="password"
id="password"
inputRef={register}
error={Boolean(errors.password)}
helperText={errors.password ? errors.password.message : " "}
/>
</Grid>
<Grid item xs={12}>
<TextField
variant="outlined"
required
fullWidth
name="passwordConfirm"
label="Confirm Password"
type="password"
id="passwordConfirm"
inputRef={register}
error={Boolean(errors.passwordConfirm)}
helperText={
errors.passwordConfirm ? errors.passwordConfirm.message : " "
}
/>
</Grid>
<Grid item xs={12}>
<FormControlLabel
control={
<Checkbox
id="termsCheck"
name="termsCheck"
color="primary"
required
/>
}
id="termsCheck"
name="termsCheck"
label={termsCheckboxLabel}
inputRef={register}
/>
<FormHelperText error>
{errors.termsCheck ? errors.termsCheck.message : " "}
</FormHelperText>
</Grid>
</Grid>
<Button
type="submit"
fullWidth
variant="contained"
color="primary"
className={classes.submit}
>
Register
</Button>
</form>
</div>
</Container>
);
}