Long Duc
Long Duc

Reputation: 112

React-hook-form validation when input is empty. Conflict with Yup.matches

I'm using React-hook-form and Yup to validation form. The field firstname I allow users to submit forms without filled this field, but if user fill this field, user can only fill string that matches my regex (my regex is check personal name). I am having the problem that when user submits the form without entering any value in the textfield, react-hook-form keeps validating and shows an error (this doesn't happen if I use Formik, but for performance reasons I have to use react-hook-form)

Link on codesanbox: https://codesandbox.io/s/react-hook-form-v7-validationschema-forked-jrqn2k?file=/src/index.js:0-898

import React from "react";
import ReactDOM from "react-dom";
import { useForm } from "react-hook-form";
import { yupResolver } from "@hookform/resolvers/yup";
import * as yup from "yup";

import "./styles.css";

const SignupSchema = yup.object().shape({
  firstName: yup.string().matches(/^[a-zA-Z ,.'-]+$/)
});

function App() {
  const {
    register,
    handleSubmit,
    formState: { errors }
  } = useForm({
    resolver: yupResolver(SignupSchema)
  });

  const onSubmit = (data) => {
    alert(JSON.stringify(data));
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <div>
        <label>First Name</label>
        <input {...register("firstName")} />
        {errors.firstName && <p>{errors.firstName.message}</p>}
      </div>

      <input type="submit" />
    </form>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

I try yup.string().nullable(true).matches(/^[a-zA-Z ,.'-]+$/) but it's not work. Hope someone can help

Upvotes: 2

Views: 3778

Answers (1)

Prashant Jangam
Prashant Jangam

Reputation: 2848

You can use .when() method. Please check updated schema below. tested and working fine in your codesandbox.

...
const SignupSchema = yup.object().shape({
  firstName: yup
    .string()
    .trim()
    .ensure()
    // .matches(/^[a-zA-Z ,.'-]+$/),
    .when({
      is: (val) => val.length > 0,
      then: yup.string().matches(/^[a-zA-Z ,.'-]+$/),
    }),
});
...

Upvotes: 3

Related Questions