Skip to content

How can I check by React Hook Form if password contains a number?

How can I check by React Hook Form and Yup if password contains a numbers, capital letters and special signs? I tried something like this below, using validate function but it doesn’t work correctly. I have an error ‘Cannot read property ‘reduce’ of undefined’.

const Register = ({ setRegisterView }) => {
  const validationSchema = Yup.object().shape({
    email: Yup.string()
      .required("It is required.")
      .email("Email is wrong"),
    password: Yup.string()
      .required("It is required.")
      .min(8, "Password need to has 8 signs.")
.validate((value) => {
        return (
          [/[a-z]/, /[A-Z]/, /[0-9]/, /[^a-zA-Z0-9]/].every((pattern) =>
            pattern.test(value)
          ) ||
          "Information"
        );
      }),
});

  const {
    register: validate,
    formState: { errors },
    handleSubmit,
  } = useForm({ mode: "onSubmit", resolver: yupResolver(validationSchema) });

  return (
    <Wrapper>
      <Form onSubmit={handleSubmit(registerProcess)}>
        <FieldType>Email</FieldType>
        <StyledInput
          name="email"
          type="email"
          error={errors.email}
          {...validate("email")}
        />
        {errors.email && <Error>{errors.email.message}</Error>}
        <FieldType>Password</FieldType>
        <StyledInput
          name="password"
          type="password"
          error={errors.password}
          {...validate("password")}
        />
        {errors.password && <Error>{errors.password.message}</Error>}
        <LoginButton type="submit">SIGN UP</LoginButton>
      </Form>
    </Wrapper>
  );
};

export default Register;

Answer

I think the problem is that you’re using validate which expects a Promise as the return value -> Docs. You should instead use test here.

const validationSchema = Yup.object().shape({
    email: Yup.string().required("It is required.").email("Email is wrong"),
    password: Yup.string()
      .required("It is required.")
      .min(8, "Password need to has 8 signs.")
      .test("passwordRequirements", "Information", (value) =>
        [/[a-z]/, /[A-Z]/, /[0-9]/, /[^a-zA-Z0-9]/].every((pattern) =>
          pattern.test(value)
        )
      )
  });

Edit React Hook Form - FieldsArray - Yup validation - Min Length (forked)