Moon
Moon

Reputation: 890

How can I set validation rules when all fields are empty React Hook Form

I'm using React Hook Form V7. I have two input fileds and using Controller to control the input. The below one is what I did now, each field is required.

<form onSubmit={handleSubmit((data) => console.log(data))}>
    <Controller
        render={({ field }) => <TextField value={field.value} onChange={field.onChange} />}
        name="test1"
        control={control}
        rules={{ required: true }}
    />
        <Controller
        render={({ field }) => <TextField value={field.value} onChange={field.onChange} />}
        name="test2"
        control={control}
        rules={{ required: true }}
    />
    <input type="submit" />
</form>

My question is how can I set instead of each one is required, I want the error message showing when both fields are empty, if only one is empty is accepted.

Is there any onSubmit validation on React Hook Form? Or I need to do the normal validation on the onSubmit function to check the value then set if error message show?

Edit: this is what I did now:

const [submitError, setSubmitError] = useState(false)
onSubmit((data) => {
    const { test1, test2 } = data
    if (!test1 && !test2) {
        setSubmitError(true)
    } else {
        setSubmitError(false)
        // do submit action
    }
})
const errorEmptyMessage = "one of test1 and test2 should has value"
return (
    <form onSubmit={handleSubmit(onSubmit)}>
        <Controller
            render={({ field }) => <TextField value={field.value} onChange={field.onChange} />}
            name="test1"
            control={control}
            rules={{ required: true }}
        />
        <Controller
            render={({ field }) => <TextField value={field.value} onChange={field.onChange} />}
            name="test2"
            control={control}
            rules={{ required: true }}
        />
        {submitError && emptyMessage}
        <input type="submit" />
    </form>
)

I wonder if React Hook Form has a built-in function to do this?

Upvotes: 4

Views: 5996

Answers (1)

Anees Hikmat Abu Hmiad
Anees Hikmat Abu Hmiad

Reputation: 3550

Is there any onSubmit validation on React Hook Form? Or I need to do the normal validation on the onSubmit function to check the value then set if error message show?

Yes, You have a nice solution which I recommend it to use nested of normal validation, its name schema validation like YUP, Simply what you need to do is add needed rule, for example (from react-hook-form):

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

const schema = yup.object({
  firstName: yup.string().required(),
  age: yup.number().positive().integer().required(),
}).required();

export default function App() {
  const { register, handleSubmit, formState:{ errors } } = useForm({
    resolver: yupResolver(schema)
  });
  const onSubmit = data => console.log(data);

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input {...register("firstName")} />
      <p>{errors.firstName?.message}</p>
        
      <input {...register("age")} />
      <p>{errors.age?.message}</p>
      
      <input type="submit" />
    </form>
  );
}

If you read the above code, you see you are build a schema for each field needed, and you have a lot of options, for example in your case you may use when to handling on x and y is empty and so on..., also you have a lot of validation schema build as an object like int, min and required, you can check this part.

Also you can do that via onSubmit on normal flow, like this:

const onSubmit = () => {
  throw new Error('Something is wrong')
}

handleSubmit(onSubmit).catch((e) => {
  // you will need to catch that error
}) 

and the idea here you check what you need and you can throw the error, exampe:

  const { register, handleSubmit } = useForm();
  const onSubmit = (data, e) => console.log(data, e);
  const onError = (errors, e) => console.log(errors, e);

  return (
    <form onSubmit={handleSubmit(onSubmit, onError)}>
      <input {...register("firstName")} />
      <input {...register("lastName")} />
      <button type="submit">Submit</button>
    </form>
  );

But from my side, I suggest to use schema validation, its really useful base on my experience with react hook form.

Update 1: More Example:

In above is example how you can build conditions to resolve issue, but simply visit yup and check when,

const schema = 
object().shape({
   a: string().when(["a", "b"], {
      is: (a, b) => !a && !b
      then: string().required("At least one is to be selected"),
      otherwise: string() // unnecessary
   }),
   a: string().when(["a", "b"], {
      is: (a, b) => !a && !b
      then: string().required("At least one is to be selected"),
      otherwise: string() // unnecessary
   })
});

Upvotes: 1

Related Questions