React hook form обработка ошибок

import React from "react"

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

import { ErrorMessage } from "@hookform/error-message"

interface FormInputs {

multipleErrorInput: string

}

export default function App() {

const {

register,

formState: { errors },

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.",

},

})}

/>

<ErrorMessage

errors={errors}

name="multipleErrorInput"

render={({ messages }) =>

messages &&

Object.entries(messages).map(([type, message]) => (

<p key={type}>{message}</p>

))

}

/>

<input type="submit" />

</form>

)

}

I’m having a hard time figuring out how to handle errors that don’t necessarily pertain to a single input field in a react-hook-form.
To put it differently, how do I handle handleSubmit errors?

For example, having the following form:

import to from 'await-to-js'
import axios, { AxiosResponse } from 'axios'
import React from "react"
import { useForm } from "react-hook-form"

type LoginFormData = {
  username: string,
  password: string,
}

export const Login: React.FC = () => {
  const { register, handleSubmit } = useForm<LoginFormData>()

  const onSubmit = handleSubmit(async (data) => {
    const url = '/auth/local'

    const [err, userLoginResult] = await to<AxiosResponse>(axios.post(url, data))
    if (userLoginResult) {
      alert('Login successful')
    }
    else if (err) {
      alert('Bad username or password')
    }
  })

  return (
    <div className="RegisterOrLogIn">
      <form onSubmit={onSubmit}>
        <div>
          <label htmlFor="username">username</label>
          <input name="username" id="username" ref={register} />
        </div>
        <div>
          <label htmlFor="password">Password</label>
          <input type="password" id="password" name="password" ref={register} />
        </div>
        <button type="submit"> </button>
      </form>
    </div>
  )
}

Is there a react-hook-form way of informing the user that there’s an error with either the username or the password?
as in, other than alert()

Perhaps this is answered elsewhere, but I could not find it.


Clarification
The error received from the server does not pertain to a single field:

{
    "statusCode": 400,
    "error": "Bad Request",
    "message": [
        {
            "messages": [
                {
                    "id": "Auth.form.error.invalid",
                    "message": "Identifier or password invalid."
                }
            ]
        }
    ],
    "data": [
        {
            "messages": [
                {
                    "id": "Auth.form.error.invalid",
                    "message": "Identifier or password invalid."
                }
            ]
        }
    ]
}

asked Oct 21, 2020 at 18:48

Joey Baruch's user avatar

Joey BaruchJoey Baruch

4,2306 gold badges34 silver badges48 bronze badges

In order to display the error from the server to your user, you need to use:

  • setError to set the error programmatically when the server returns an error response.
  • errors to get the error state of every fields in your form to display to the user.
type FormInputs = {
  username: string;
};

const { setError, formState: { errors } } = useForm<FormInputs>();

In your handleSubmit callback

axios
  .post(url, data)
  .then((response) => {
    alert("Login successful");
  })
  .catch((e) => {
    const errors = e.response.data;

    if (errors.username) {
      setError('username', {
        type: "server",
        message: 'Something went wrong with username',
      });
    }
    if (errors.password) {
      setError('password', {
        type: "server",
        message: 'Something went wrong with password',
      });
    }
  });

In your component

<label htmlFor="username">username</label>
<input id="username" {...register("username")} />
<div>{errors.username && errors.username.message}</div>

Live Demo

Edit 64469861/react-hook-form-handling-errors-in-handlesubmit

answered Oct 22, 2020 at 9:07

NearHuscarl's user avatar

NearHuscarlNearHuscarl

67.7k18 gold badges266 silver badges232 bronze badges

1

Inspired by @NearHuscarl’s answer, I’ve done the following hack s.t. changes in either the username or the password inputs will remove the single error.

This hack does not scale well if your error is related to multiple fields in the form, but it worked for the login use case.

onSubmit:

const onSubmit = handleSubmit(async (data) => {
    const url = '/auth/local'

    const [err, userLoginResult] = await to<AxiosResponse>(axios.post(url, data)) // see await-to-js 
    if (userLoginResult) {
      alert('Login successful')
    }
    else if (err) {
      const formError = { type: "server", message: "Username or Password Incorrect" }
      // set same error in both:
      setError('password', formError)
      setError('username', formError)
    }
  })

component:

  return (
    <div className="RegisterOrLogIn">
      <form onSubmit={onSubmit}>
        <div>
          <label htmlFor="username">username</label>
          <input name="username" id="username" ref={register} />
        </div>
        <div>
          <label htmlFor="password">Password</label>
          <input type="password" id="password" name="password" ref={register} />
        </div>
        <div>{errors.username && errors.password?.message /*note the cross check*/}</div>
        <button type="submit"> </button>
      </form>
    </div>
  )

by setting and rendering the error on both errors.password & errors.username, the error will disappear when the user updates either of those fields.

answered Oct 22, 2020 at 19:40

Joey Baruch's user avatar

Joey BaruchJoey Baruch

4,2306 gold badges34 silver badges48 bronze badges

2

Since v7.43.0, you can use the syntax root.xxx error to handle server error or some global level error.

const onSubmit = () => {
  try {
    fetch(...)
    if (response.statusCode > 300) {
        setError('root.serverError', { 
          type: response.statusCode,
          message: e.message,
          // meta: {}, // something to be consider to included in the phase 2 with meta object
        })
    }
  } catch(e) {
    setError('root.serverCatch', { 
      type: 'server',
      message: e.message
    })
  }
}

const onClick = () => {
  setError('root.random', { 
    type: 'random', 
    message: 'random' 
  })
}

return (
  <>
    {errors.root.serverError.type === 400 && <p>server response message</p>}
    <p>{errors.root.serverError.message}</p>
    
    {errors.root.serverCatch.type === 'server' && <p>server error message</p>}
    <p>{errors.root.serverCatch.message}</p>
    
    <p>{errors.root.random.message}</p>
  </>
)

RFC

answered Jul 25 at 10:49

pom421's user avatar

pom421pom421

1,74119 silver badges38 bronze badges

According to documentation of react-hook-form I can use name of input element like this «xxx.yyy» and this will result in my prepared data to be

{ xxx: { yyy: value }}

But when I try to use this feature with ‘errors’ I cannot use it. i.e. I cannot write below:

{errors.xxx.yyy && <span>This field is required</span>}

because I get «Cannot read property ‘yyy’ of undefined».

Documentation says that I should use this chaining operator, ?. , so I try it:

{errors?.xxx?.yyy && <span>This field is required</span>}

But nothing displays on the page if required input is omitted. I can see that the mechanism blocks form from being submitted until I write something in this field, that is OK, but why I don’t get the error message on the page?

Bill's user avatar

Bill

17.9k19 gold badges84 silver badges132 bronze badges

asked Dec 23, 2019 at 12:40

YotKay's user avatar

it really depend which version you are using.

V3: flat error object

errors['xxx.yyyy']

V4: Nested errors object with better type support

errors?.xxx?.yyyy

we have also build a ErrorMessage component which you may find it useful.

https://react-hook-form.com/api#ErrorMessage

answered Dec 31, 2019 at 5:04

Bill's user avatar

BillBill

17.9k19 gold badges84 silver badges132 bronze badges

Ok, I found answer myself. I should use this form:

{errors[‘xxx.yyy’] && This field is required}

Then everything works :-)

answered Dec 23, 2019 at 13:00

YotKay's user avatar

YotKayYotKay

1,1271 gold badge9 silver badges25 bronze badges

you don’t want to spend your coding time. you can use @hookform/error-message instead of code manually. it’s very easy. it’ll manage those errors.
just pass the errors object given by react-hook-form and pass the property name that you want to display the error message.

<ErrorMessage errors={errors} name="xxx.yyy" message="This is required" /> 

OR

if you want to customize your message as you want, you can render as you want like below.
think that you want to bold and show invalid with red custom css class. then you can render as you want.

<ErrorMessage render={({message}) => <div className="invalid-feedback d-block"><b> {message} </b></div>} errors={errors} name="xxx.yyy"/>

NPM https://www.npmjs.com/package/@hookform/error-message

answered Dec 31, 2020 at 11:47

Mafei's user avatar

MafeiMafei

3,1313 gold badges15 silver badges37 bronze badges

React Hook Form Logo - React hook custom hook for form validation

Performant, flexible and extensible forms with easy to use validation.

npm downloads
npm
npm

Goal

A simple component to render associated input’s error message.

Install

$ npm install @hookform/error-message

Quickstart

  • Single Error Message
import React from 'react';
import { useForm } from 'react-hook-form';
import { ErrorMessage } from '@hookform/error-message';

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

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input
        name="singleErrorInput"
        ref={register({ required: 'This is required.' })}
      />
      <ErrorMessage errors={errors} name="singleErrorInput" />

      <ErrorMessage
        errors={errors}
        name="singleErrorInput"
        render={({ message }) => <p>{message}</p>}
      />

      <input name="name" ref={register({ required: true })} />
      <ErrorMessage errors={errors} name="name" message="This is required" />

      <input type="submit" />
    </form>
  );
}

  • Multiple Error Messages
import React from 'react';
import { useForm } from 'react-hook-form';
import { ErrorMessage } from '@hookform/error-message';

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

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input
        name="multipleErrorInput"
        ref={register({
          required: 'This is required.',
          pattern: {
            value: /d+/,
            message: 'This input is number only.',
          },
          maxLength: {
            value: 10,
            message: 'This input exceed maxLength.',
          },
        })}
      />
      <ErrorMessage
        errors={errors}
        name="multipleErrorInput"
        render={({ messages }) =>
          messages &&
          Object.entries(messages).map(([type, message]) => (
            <p key={type}>{message}</p>
          ))
        }
      />

      <input type="submit" />
    </form>
  );
}

API

Prop Type Required Description
name string Associated field name.
errors object errors object from React Hook Form. It’s optional if you are using FormProvider.
message string | React.ReactElement inline error message.
as string | React.ReactElement | React.ComponentType Wrapper component or HTML tag. eg: as="p", as={<p />} or as={CustomComponent}. This prop is incompatible with prop render and will take precedence over it.
render Function This is a render prop for rendering error message or messages.
Note: you need to set criteriaMode to all for using messages.

Backers

Thank goes to all our backers! [Become a backer].

Contributors

Thanks goes to these wonderful people. [Become a contributor].

As a React developer, you must know how to implement validation in form, and a form may hold one or more than one input element.

If you want to get the user-provided data in a subtle manner, then you must show reverence to proper error handling.

In this tutorial, we would like to show you how to add validation in React, show appropriate error messages in React application using Hook Form and Yup packages.

Let us understand what error messages are and why they should be displayed to the user.

Seldom, a user enters incorrect values into the form fields, and you must have seen some error messages manifest on the screen. These messages help in hinting your users about their blunders.

As per the common notion, error messages play a vital role in such a scenario and help users easily determine the issue. After that, users can quickly fix it and submit the form with absolutely no error.

How to Use React Hook Form to Show Validation Error Messages

  • Step 1: Set Up React Project
  • Step 2: Add Bootstrap Library
  • Step 2: Add Yup and Hook Form Plugins
  • Step 3: Create Form Component File
  • Step 4: List Form Module in App Js
  • Step 5: Run Development Server

Set Up React Project

First step tells you how to deal with blank React project installation.

On the terminal screen, you have to type the given command and quickly execute it.

npx create-react-app react-shine

Carefully enter into the project folder.

cd react-shine

Add Bootstrap Library

This instruction is for adding the bootstrap in React app. Now, you have to add the library so run the following command.

npm install bootstrap

Here, you have to include and use the bootstrap UI component in React. Ensure that you are importing the bootstrap CSS path in App.js file.

import React from 'react'
import 'bootstrap/dist/css/bootstrap.min.css'
export default function App() {
  return (
    <>
     
    <>
  )
}

Add Yup and Hook Form Plugins

Let us install the yup and hook form plugins, you have to use the provided command to add the libraries.

npm install @hookform/resolvers yup

Create Form Component File

We are going to build a new component, this file will have the code to show error messages.

Therefore, open the component/ folder and make a new file inside the folder. You can name it ErrorMsg.js file.

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

export default function ErrorMsg() {
  const yupValidation = Yup.object().shape({
    name: Yup.string()
      .required('Please enter some value.')
      .min(4, 'Add minimum 4 characters'),
    email: Yup.string().required('Email id is mendatory').email(),
  })
  const formOptions = { resolver: yupResolver(yupValidation) }
  const { register, handleSubmit, reset, formState } = useForm(formOptions)
  const { errors } = formState
  function onSubmit(data) {
    console.log(JSON.stringify(data, null, 4))
    return false
  }
  return (
    <div className="container mt-4">
      <h2>React Integrate Validation Error Messages with Hook Form</h2>
      <form onSubmit={handleSubmit(onSubmit)}>
        <div className="form-group">
          <label>Name</label>
          <input
            name="name"
            type="text"
            className={`form-control ${errors.name ? 'is-invalid' : ''}`}
            {...register('name')}
          />
          <div className="invalid-feedback">{errors.name?.message}</div>
        </div>
        <div className="form-group">
          <label>Email</label>
          <input
            name="email"
            type="text"
            className={`form-control ${errors.email ? 'is-invalid' : ''}`}
            {...register('email')}
          />
          <div className="invalid-feedback">{errors.email?.message}</div>
        </div>
        <div className="mt-3">
          <button type="submit" className="btn btn-primary">
            Send
          </button>
        </div>
      </form>
    </div>
  )
}

List Form Module in App Js

This instruction is all about listing the error message component in React’s main app component file.

Hence, open the src/App.js and import the component as shown below.

import React from 'react'
import ErrorMsg from './components/ErrorMsg'
import 'bootstrap/dist/css/bootstrap.min.css';

export default function App() {
  return (
    <div className="App">
      <ErrorMsg />
    </div>
  )
}

Run Development Server

Lastly, you have to open the terminal again type the command and press enter.

npm start

Here is the url that you can use to check the app on the browser.

http://localhost:3000

React Display Validation Error Messages with Hook Form Tutorial

Conclusion

We built a simple form with only two input controls name and email. And learned how to set validation error messages in React app using hook form and yup libraries.

Not just that, we also determine how to set form from the absolute beginning.

Понравилась статья? Поделить с друзьями:
  • React wad ошибка
  • Realtek audio console microsoft store ошибка
  • Reached end of file while parsing java ошибка
  • Red alert 3 ошибка 5 0000065434
  • Red alert 2 фатальная ошибка