ErrorMessage
Render validation error messages for a field.
</> ErrorMessage: Component Since v7.88.0
A simple component to render associated input's error message. Reads from the control prop when supplied, otherwise from the nearest FormProvider.
Props
| Name | Type | Required | Description |
|---|---|---|---|
name | string | ✓ | Name of the field, or a global error path (root or root.*). |
control | Control | control object provided by useForm. Optional if you are using FormProvider. | |
as | React.ElementType | Wrapper component or HTML tag. For example: as="span" or as={Text} | |
render | ({ message: string, messages?: Object}) => React.ReactNode | This is a render prop for rendering error message or messages. Note: you need to set criteriaMode to 'all' for using messages. |
Examples
Single Error Message
import { useForm, ErrorMessage } from "react-hook-form"interface FormInputs {singleErrorInput: string}export default function App() {const { register, control, handleSubmit } = useForm<FormInputs>()const onSubmit = (data: FormInputs) => console.log(data)return (<form onSubmit={handleSubmit(onSubmit)}><input{...register("singleErrorInput", { required: "This is required." })}/><ErrorMessage control={control} name="singleErrorInput" /><ErrorMessagecontrol={control}name="singleErrorInput"render={({ message }) => <p>{message}</p>}/><input type="submit" /></form>)}
import { useForm, ErrorMessage } from "react-hook-form"export default function App() {const { register, control, handleSubmit } = useForm()const onSubmit = (data) => console.log(data)return (<form onSubmit={handleSubmit(onSubmit)}><input{...register("singleErrorInput", { required: "This is required." })}/><ErrorMessage control={control} name="singleErrorInput" /><ErrorMessagecontrol={control}name="singleErrorInput"render={({ message }) => <p>{message}</p>}/><input type="submit" /></form>)}
Multiple Error Messages
import { useForm, ErrorMessage } from "react-hook-form"interface FormInputs {multipleErrorInput: string}export default function App() {const { register, control, handleSubmit } = useForm<FormInputs>({criteriaMode: "all",})const onSubmit = (data: FormInputs) => console.log(data)return (<form onSubmit={handleSubmit(onSubmit)}><input{...register("multipleErrorInput", {required: "This is required.",pattern: {value: /\d+/,message: "This input is number only.",},maxLength: {value: 10,message: "This input exceed maxLength.",},})}/><ErrorMessagecontrol={control}name="multipleErrorInput"render={({ messages }) =>messages &&Object.entries(messages).map(([type, message]) => (<p key={type}>{message}</p>))}/><input type="submit" /></form>)}
import { useForm, ErrorMessage } from "react-hook-form"export default function App() {const { register, control, handleSubmit } = useForm({criteriaMode: "all",})const onSubmit = (data) => console.log(data)return (<form onSubmit={handleSubmit(onSubmit)}><input{...register("multipleErrorInput", {required: "This is required.",pattern: {value: /\d+/,message: "This input is number only.",},maxLength: {value: 10,message: "This input exceed maxLength.",},})}/><ErrorMessagecontrol={control}name="multipleErrorInput"render={({ messages }) =>messages &&Object.entries(messages).map(([type, message]) => (<p key={type}>{message}</p>))}/><input type="submit" /></form>)}
With FormProvider
import { useForm, FormProvider, ErrorMessage } from "react-hook-form"function Field() {return <ErrorMessage name="singleErrorInput" />}export default function App() {const methods = useForm()return (<FormProvider {...methods}><form onSubmit={methods.handleSubmit((data) => console.log(data))}><input{...methods.register("singleErrorInput", {required: "This is required.",})}/><Field /><input type="submit" /></form></FormProvider>)}
Tips
-
asonly wraps the message text and does not receive other props. To add a class name, anidforaria-describedby, orrole="alert", userender:<ErrorMessagename="email"render={({ message }) => (<p id="email-error" role="alert" className="field-error">{message}</p>)}/> -
Each
ErrorMessagesubscribes only to the errors for itsname, so you can use many of them without re-rendering the whole form. -
Use
name="root.server"to show the error set by theFormcomponent, or any root error you set withsetError.
Troubleshooting
The field is invalid but ErrorMessage renders nothing
Why it happens
The validation rule may not include a message. For example, required: true creates an error without display text, so the default renderer has nothing to show.
Fix
Give each rule a message, or use render to provide a fallback:
<input {...register("email", { required: "Email is required" })} /><ErrorMessagename="email"render={({ message }) => <p role="alert">{message || "Invalid value"}</p>}/>
messages is undefined in the render prop
Why it happens
React Hook Form stores all failed rules in messages only when the form uses criteriaMode: "all". The default mode keeps the first relevant error.
Fix
Initialize the form with useForm({ criteriaMode: "all" }), or render the single message value instead.
ErrorMessage cannot find the form control
Why it happens
No control prop was passed and the component is outside a FormProvider.
Fix
Pass control from useForm, or place ErrorMessage inside <FormProvider {...methods}>.