user8758206
user8758206

Reputation: 2191

Why does react hook form errors object temporarily empty?

I'm trying to understand why the errors object in the react hook form becomes empty, even after an error is set to it. I've built a demo in a code sandbox which should help explain this much clearer.

So I have a function that runs after changing the field:

  const onNameChange = async ({ target: { value } }) => {
    setValue("name", value);
    const valid = await trigger("name");
    console.log("valid", valid, "value", value);
    if (!valid) {
      return;
    }
    getPokemonDebounced(value);
    setShowPokemon(false);
  };

Which runs the getPokemonDebounced function:

 const getPokemon = async (input) => {
    console.log("getPokemon Fn");
    try {
      const res = await axios.get(`https://pokeapi.co/api/v2/pokemon/${input}`);
      console.log(res);
      const { data } = res;
      if (data) {
        setPokemon(data);
        setFetchError(null);
      }
      console.log(res);
    } catch (error) {
      setPokemon(null);
      setFetchError(error);
      setError("name", { type: "manual", message: "CUSTOM name error" });
    }
  };

  // why does the errors object temporarily become blank? nothing seems to set it to blank

  const getPokemonDebounced = useDebounce(500, getPokemon);

Which sets an error when an API-call fails. However, I noticed that the errors object becomes empty under this circumstance:

  1. Visit the demo: https://codesandbox.io/s/react-playground-forked-tv0cm?file=/Pokemon.js
  2. Open the console (at the bottom-left of the display)
  3. Type in some gibberish into the field, like 'wefhiwd'
  4. Wait a moment for the errors object to log (should have a name key)
  5. Type in 1 more letter into the field, and you'll see that the errors object is logged and is temporarily an empty object {} until the getPokemonDebounced runs and fails to fetch to set an error

My question is why does the errors object become empty {} again immediately after typing another letter? After typing in the initial gibberish it then set the errors object to contain an error, and I can't see how it becomes empty again temporarily.

The form:

<form onSubmit={handleSubmit(onSubmit /*, onError*/)}>
        <input
          {...register("name", { required: true })}
          name="name"
          placeholder="Enter a pokemon"
          onChange={onNameChange}
        />
        <button type="submit" onClick={onSubmit}>
          Show Pokemon
        </button>
        {errors.name && <p>{errors.name.message}</p>}
      </form>

Thanks for any help

Upvotes: 2

Views: 7056

Answers (1)

vitjbr
vitjbr

Reputation: 1166

Because on change of your input, you run the validation again and it clears the errors on all valid fields.

  const onNameChange = async ({ target: { value } }) => {
    setValue("name", value);
    const valid = await trigger("name"); // here you trigger validation that will clear the error if the field is valid
    console.log("valid", valid, "value", value);
    if (!valid) { // if invalid nothing happens
      return;
    }
    getPokemonDebounced(value); // if valid do the call which will set the new error on fail
    setShowPokemon(false);
  };

if you'd set error with name that is not associated with an input, it will persist.

setError("randomError", { type: "manual", message: "RANDOM name error" });

From the docs - https://react-hook-form.com/api/useform/seterror/

 - This method will not persist the associated input error if the input passes validation.

 - An error that is not associated with an input field will be persisted until cleared with clearErrors.

Upvotes: 3

Related Questions