2

I ant to implement a form with react-hook-form. I tried this:

....
 <form onSubmit={handleSubmit(onSubmit)} className='mt-4 register-form'>
            <div className='row'>
              <div className='col-sm-6'>
                <div className='input-group mb-3'>
                  <Controller
                      control={control}
                      name={"name"} //  the key of json
                      defaultValue={""}
                      render={({ field }) => (
                          <input
                              {...field}
                              type="text"
                              className="form-control"
                              placeholder="Name"
                              aria-label="name"
                              onChange={(e) => field.onChange(e.target.value)}
                          />
                      )}
                  />
                </div>
              </div>
.....

Full page code:

https://pastebin.com/KZzsLZAn

When I submit the form I send a POST message using:

import axios from "axios";
import React from "react";

const baseURL = "https://jsonplaceholder.typicode.com/posts";

export const SubmitContact = (json) => {
    return axios.post(baseURL, json);
};

But there is no validation message into the form and no final message that the form is successfully summitted.

Do you know how I can implement this functionality?

1
  • Adding validation: react-hook-form.com/get-started/#Applyvalidation checking if sent successfully: if setPost in your onSubmit is reached, sending the data worked (also note that you called the parameter json but it's an object, not json; json is a text format that looks like a JS object literal) (also the initial value of post should be {}) Commented Aug 14, 2022 at 13:06

3 Answers 3

1
+50

Try getting the errors from useForm like so:

const { errors, ...rest } = useForm();

<div className="col-sm-6">
  <div className="input-group mb-3">
    <Controller
      control={control}
      name={"name"} //  the key of json
      defaultValue={""}
      rules={{ required: true }}
      render={({ field }) => (
        <input
          {...field}
          type="text"
          className="form-control"
          placeholder="Name"
          aria-label="name"
          onChange={(e) => field.onChange(e.target.value)}
        />
      )}
    />
    {errors.name && (
      <div className="alert alert-danger">{errors.name.message}</div>
    )}
  </div>
</div>;
Sign up to request clarification or add additional context in comments.

6 Comments

I have one additional question: When I submit the form, fields into the form are not cleared. Any idea why?
Well that's normal. Inputs are not meant to be cleared after onSubmit — with errors. What gets cleared are any possible errors while they are solved by the user.
Do you know how I can implement it?
I tried the code but I get ContactsForm.js:45 Uncaught TypeError: Cannot read properties of undefined (reading 'name')
Rules are not defined correctly here
|
1

You are not using the rules correctly in Controller component, you don't need to define the name of registered input, you just have to say rules:

rules={{ 
   required: "Required", // Note you are wrapping this inside a key which is not required
}}

To access this error messages, you need to use formState from useForm

const {formState: {errors}} = useForm()

// accessing errors
{errors.country?.message}

In order to clear form just use reset

Here's a working sandbox of your code: https://codesandbox.io/s/late-haze-jivrwp?file=/src/App.js

On submit you can see the error popping up on country field

Comments

1

To display error message:

const { control, handleSubmit, formState: { errors } } = useForm();

...

<form onSubmit="{handleSubmit(onSubmit)}" className="mt-4 register-form">
  <div className="row">
    <div className="col-sm-6">
      <div className="input-group mb-3">
        <Controller 
          control={control} 
          name="name"
          defaultValue="" 
          rules={{ required: true }}
          render={({ field }) => ( 
            <input 
             {...field} 
             type="text"
             className="form-control" 
             placeholder="Name" 
             aria-label="name"
             onChange={(e) => field.onChange(e.target.value)} 
            /> 
           )} 
         />
         {errors.name && <p>{errors.name.message}</p>}
      </div>
    </div>
  </div>
</form>

To reset the form after submission:

const { control, reset, handleSubmit, formState: { errors } } = useForm();

...

const onSubmit = (formData) => {
    try {
      SubmitContact(formData).then((res) => {
        setPost(res.data);
        reset();
      });
    } catch (e) {
      console.error(e);
    }
};

3 Comments

you need to define rules as well
What kind of rules are you talking about? @YashJoshi
when you use the controller you need to define rules in order to show an error message, as of now it doesn't have any. Also, we get errors in formState now, Ref: react-hook-form.com/api/useform/formstate

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.