16

I'm using React Hook Form in order to validate some simple inputs :

import React from "react";
import useForm from "react-hook-form";

import "./App.css";

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

  return (
    <div className="App">
      <header className="App-header">
        <form onSubmit={handleSubmit(onSubmit)}>
          <input
            className="mkn-input"
            name="firstName"
            placeholder="First name"
            ref={register({
              required: true,
              maxlength: 20,
              message: "invalid first name"
            })}
          />
          <span> {errors.firstName && errors.firstName.message}</span>

          <input
            placeholder="Last name"
            className="mkn-input"
            name="lastName"
            ref={register({
              pattern: /^[A-Za-z]+$/i,
              message: "Invalid last name"
            })}
          />
          {errors.lastName && <span> errors.lastName.message</span>}
          <input
            name="age"
            type="number"
            placeholder="Age"
            className="mkn-input"
            ref={register({ min: 18, max: 99 })}
          />
          <input type="submit" className="mkn-btn" />
        </form>
      </header>
    </div>
  );
}

export default App;

But I'm facing a weird issue with showing that errors in the DOM, i also to tried to log them in console but without success, what am I missing ?

the full code :

Edit React Hook Form - Custom Input

1
  • 2
    In RHF v7, useForm returns a fieldState object which in turn holds the errors. But beware that fieldState is some kind of proxy object and will always log as empty {} even when there are errors! Commented Aug 22, 2022 at 16:41

4 Answers 4

10

You need to add the message in the required field, or just query if there is an error:

<>
  <input
    name="firstName"
    placeholder="First name"
    ref={register({
      required: 'invalid first name'
    })}
  />
  <span> {errors.firstName && errors.firstName.message}</span>
</>

// Or 
<>
  <input
    placeholder="Last name"
    className="mkn-input"
    name="lastName"
    ref={register({
      required: true,
      pattern: /^[A-Za-z]+$/i
    })}
  />
  {errors.lastName && <span>Invalid last name</span>}
</>

// Or https://react-hook-form.com/advanced-usage#ErrorMessage
function App() {
  const { register, handleSubmit, errors } = useForm();
  const onSubmit = data => {
    console.log(data);
  };

  return (
    <div className="App">
      <header className="App-header">
        <form onSubmit={handleSubmit(onSubmit)}>
          <input
            className="mkn-input"
            name="firstName"
            placeholder="First name"
            ref={register({
              required: 'invalid first name'
            })}
          />
          <span> {errors.firstName && errors.firstName.message}</span>

          <input
            placeholder="Last name"
            className="mkn-input"
            name="lastName"
            ref={register({
              required: true,
              pattern: /^[A-Za-z]+$/i
            })}
          />
          {errors.lastName && <span>Invalid last name</span>}
          <input
            name="age"
            type="number"
            placeholder="Age"
            className="mkn-input"
            ref={register({ min: 18, max: 99 })}
          />
          <input type="submit" className="mkn-btn" />
        </form>
      </header>
    </div>
  );
}

Edit React Hook Form - Custom Input

Sign up to request clarification or add additional context in comments.

2 Comments

In v7, errors is within formState: const { formState: { errors } } = useForm();. See docs.
true formState : { errorsr } in v7, but it still doesn't log the errors sometimes. I'm experiencing this now with trying to implement custom scroll to events. Quite frustrating.
0

It worked after installing this component to render associated input's error message.

npm install @hookform/error-message

Here's an example for implementation:

 <input
        {...register("multipleErrorInput", {
          required: "This is required.",
          pattern: {
            value: /d+/,
            message: "This input is number only.",
          },
          maxLength: {
            value: 10,
            message: "This input exceed maxLength.",
          },
        })}
      />
<div>
    {errors.multipleErrorInput && (
                      <div className="text-red-500 mt-4">
                        <span>{errors.multipleErrorInput.message}</span>
                      </div>
                    )}
</div>

More info here: https://react-hook-form.com/docs/useformstate/errormessage

Comments

0

May be a litte bit late but I would like what works for me:

import { FC, useState } from "react";
import { useRoles } from "../../hooks";
import Select, { SingleValue } from "react-select";
import { Option } from "../../types/types";
import { UseFormRegister } from "react-hook-form";
import { CreateUserDto } from "../../api";

type Props = {
  onSelect: (role: Option | null) => void;
  register: UseFormRegister<CreateUserDto>;
};

export const RolesSelect: FC<Props> = ({ onSelect, register }) => {
  const { rolesOptions } = useRoles();
  const [selectedRole, setSelectedRole] = useState<SingleValue<Option>>();

  const onChange = (option: SingleValue<Option>) => {
    setSelectedRole(option);
    onSelect(option);
  };

  return (
    <Select
      {...register("roleId", {
        required: "El rol es requerido",
      })}
      name="roleId"
      options={rolesOptions}
      value={selectedRole}
      onChange={onChange}
    />
  );
};

And in my form

...
  const {
    register,
    handleSubmit,
    control,
    formState: { errors },
  } = useForm<UserForm>();

return   <RolesSelect
            register={register}
            onSelect={(d) => {
              console.log(d);
            }}
          />

Comments

-3

In our case (with [email protected]) this was caused by React.StrictMode.

Removing React.StrictMode or running the code in production resolves the issue.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.