25

I've tried using the "reset" function form react-hook-form but after submitting the input fields are not emptying. I don't know why exactly, I"m sure I"m missing something but cannot find what.

Here's my code:

const Form = () => {
  const [values, setValues] = useState({
    email: "",
    name: "",
    subject: "",
    description: "",
  });

  const { register, handleSubmit, reset, errors } = useForm();


  toastr.options = {"positionClass": "toast-top-right","progressBar": true,}
  const onSubmit = (values, e) => {
    
    const { email, name, subject, description } = values;
    axios.post("http://localhost:8080/sendme", {
      email,
      name,
      subject,
      text: description,
    });
   
    e.target.reset();
    toastr.success('Message was sent successfully!');
   
  };

  const handleChange = (e) => {
    const { name, value } = e.target;
    setValues({
      ...values,
      [name]: value,
    });
    
  };


  return (
    <div>
      <form onSubmit={handleSubmit(onSubmit)} noValidate>
        <div className="inputField">
          <input
            className={`${errors.email && "inputError"}`}
            name="email"
            type="email"
            ref={register({ required: true, pattern: /^\S+@\S+$/i })}
            placeholder="Your email *"
            value={values.email}
            onChange={handleChange}
          />
          <ErrorMessage error={errors.email} />
        </div>
        <div className="inputField">
          <input
            className={`${errors.name && "inputError"}`}
            name="name"
            type="text"
            placeholder="Your name *"
            ref={register({ required: true })}
            value={values.name}
            onChange={handleChange}
          />
          <ErrorMessage error={errors.name} />
        </div>
        <div className="inputField">
          <input
            className={`${errors.subject && "inputError"}`}
            name="subject"
            type="text"
            placeholder="Subject *"
            ref={register({ required: true })}
            value={values.subject}
            onChange={handleChange}
          />
          <ErrorMessage error={errors.subject} />
        </div>
        <div className="inputField">
          <p className="reqTxt"> * = Required</p>
          <textarea
            className={`${errors.description && "inputError"}`}
            name="description"
            placeholder="Type your message here *"
            ref={register({ required: true, minLength: 15 })}
            value={values.description}
            onChange={handleChange}
            rows="15"
            cols="80"
          ></textarea>
          <ErrorMessage error={errors.description} />
        </div>

        <button className="btn" onClick={reset} type="submit">
          Send message
        </button>
      </form>
    </div>
  );
};

I've imported the reset and used it with onClick but it doesn't seem to work. How should I fix this?

6
  • 1
    I think you completely miss the point of react hook form, it's uncontrolled. have a good read this page: react-hook-form.com/get-started, i think you will find yourself remove quite a lot of code. Commented Jul 24, 2020 at 3:50
  • @Bill Can you be more specific of what I'm doing wrong here, please? Commented Jul 25, 2020 at 16:36
  • 1
    follow this video: youtube.com/watch?v=bU_eq8qyjic you will see what's the missing part. you shouldn't need to use useState with hook form. Commented Jul 26, 2020 at 11:05
  • 1
    I read more as you said, that was so stupid of me, I managed to get it to work now and saw were I messed up, you can submit an answer if you want, I shoud read more on what I'm using next time, Thank you Commented Jul 26, 2020 at 11:23
  • 1
    @Bill indeed, I overcomplicated it Commented Jul 26, 2020 at 14:11

7 Answers 7

21

Make logic, whenever you want to reset your input. just invoke the reset method

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

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

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <label htmlFor="firstName">First name</label>
      <input
        id="firstName"
        type="text"
        aria-invalid={errors.firstName ? "true" : "false"}
        name="firstName"
        ref={register({ required: true })}
      />

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

cheer you!

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

1 Comment

This isn't what the docs state: "It's recommended to not invoke reset inside onReset or onSubmit callback." "Because onSubmit callback is async and includes its validation when reset inside the callback it will intercept the result of formState update. This will be problematic when you subscribed to the formState."
10

You can use

reset({});

This piece of code reset all your form

1 Comment

Useful answer : calling reset() does nothing. The empty object passed to reset will state for new values. Even better, reset(defaultValues) if you have defaultValues.
9

When you using react-hook-form, you are most likely can skip using useState:

https://react-hook-form.com/get-started

Here is a quick example at the get started page:

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

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

  console.log(watch("example")); // watch input value by passing the name of it

  return (
    {/* "handleSubmit" will validate your inputs before invoking "onSubmit" */}
    <form onSubmit={handleSubmit(onSubmit)}>
    {/* register your input into the hook by invoking the "register" function */}
      <input name="example" defaultValue="test" ref={register} />
      
      {/* include validation with required or other standard HTML validation rules */}
      <input name="exampleRequired" ref={register({ required: true })} />
      {/* errors will return when field validation fails  */}
      {errors.exampleRequired && <span>This field is required</span>}
      
      <input type="submit" />
    </form>
  );
}

Comments

4

try this:

const submit = (data, e)=>{
      console.log(data);
      e.target.reset();
}

Comments

4

Additionally to the other comments, react-hook-form doc suggests to use reset in a useEffect hook:

const { reset, formState: { isSubmitSuccessful } } = useForm()

useEffect(() => {
  if (!isSubmitSuccessful) { return }

  reset({
    email: "",
    name: "",
    subject: "",
    description: ""
  })
}, [isSubmitSuccessful])

Comments

1

If you want to reset only specific fields, and keep the rest unchanged (to avoid having to retype everything), you can specify like this for instance:

    reset({currentPassword: ""});

Comments

0

Hell no,

To reset all values just use reset() method.

Documentation

In the other hand, I see that this method doesn't work on Edge, and FF, but it works on chrome perfectly.

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.