skip to Main Content

I am developing a wizard setup for the company I work for, this wizard will be used for the sign in flow when a user try to create an account.

For each step I conditionally render different inputs, when the input or inputs of the actual step of the setup are valid, the user can go to the next step.

To achieve this, I need to know if the invalid property of the inputs or input in the current page is false, to achieve this I am using react hook form ^7.43.9 and getFieldState of the useForm hook.

The problem is that the invalid property is always false in first render, it has to be true at first render.

I simplified the code for you, this code only checks if firstName.invalid (line:15) is false, if it is false, the user can continue, if not, the user has to try again.

The validation for firstName is min 3 chars and it is required, if you click the button with no value, you are able to go to the next step, and this is wrong because validation rules are never applied.

Is there any way to make invalid true in first render?

Is there another way to know if the current inputs are valid?

Here is the code:

import { useState } from "react";
import { useForm } from "react-hook-form";

export default function App() {
  const [step, setstep] = useState(1);
  const {
    register,
    getFieldState,
    // I subscribed to errors as the documentation says
    formState: { errors },
  } = useForm({
    mode: "onChange",
  });

  const handleStep = () => {
    const firstName = getFieldState("firstName");
    if (firstName.invalid) {
      alert("oh no, invalid is true, so try again");
    } else {
      alert("excelente, invalid is false, so you can go next step");
    }
  };

  return (
    <form style={{ padding: "1rem" }}>
      <h1>Step 1</h1>
      <input {...register("firstName", { required: true, min: 3 })} />
      <button type="button" onClick={() => handleStep()}>
        Continue
      </button>
    </form>
  );
}

You can try it on codesandbox:

https://codesandbox.io/s/upbeat-jennings-vbz1vf?file=/src/App.tsx

This is the link to the documentarion about how to use getFieldState

https://react-hook-form.com/api/useform/getfieldstate/

I appreciate your help

2

Answers


  1. If I understand you correctly you want to essentially validate your form values on the component mounting.

    I that case you can use the trigger function provided by useForm. And then call that upon the component mounting using the useEffect lifecycle hook.

    You solution would look something like this:

    const {
      register,
      getFieldState,
      formState: { errors },
      trigger // add this variable
    } = useForm({
      mode: "onChange",
    });
    
    useEffect(() => {
      trigger(); // triggers all form validations when component is mounted
    }, [])
    

    Additional Issue

    Including the answer @adsy mentioned here as well because this is a separate bug you’re also facing.

    You should do:

    <input {...register("firstName", { required: true, minLength: 3 })} />
    

    Because min refers to a numeric minimum, but you’re talking about string length, so minLength should be used here.

    Login or Signup to reply.
  2. I think you meant

    <input {...register("firstName", { required: true, minLength: 3 })} />
    

    I.e. minLength and not min. Which is about numerical values.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search