React-hook-form's 'reset' is working properly, input fields are still not emptying after submit
Asked Answered
C

7

24

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?

Cupriferous answered 23/7, 2020 at 15:39 Comment(6)
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.Jem
@Jem Can you be more specific of what I'm doing wrong here, please?Cupriferous
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.Jem
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 youCupriferous
not stupid at all, we all make similar mistakes by skipping the doc. hopefully, you can see hook from can make your form much simpler :)Jem
@Jem indeed, I overcomplicated itCupriferous
J
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>
  );
}
Jem answered 26/7, 2020 at 13:7 Comment(0)
P
20

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!

Procrustean answered 10/10, 2020 at 5:49 Comment(1)
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."Louanneloucks
J
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>
  );
}
Jem answered 26/7, 2020 at 13:7 Comment(0)
H
8

You can use

reset({});

This piece of code reset all your form

Holmic answered 16/11, 2021 at 23:12 Comment(1)
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.Swinger
S
4

try this:

const submit = (data, e)=>{
      console.log(data);
      e.target.reset();
}
Sacrilegious answered 5/3, 2021 at 8:55 Comment(0)
C
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])
Cockleboat answered 10/5, 2023 at 11:17 Comment(0)
L
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: ""});
Lorianne answered 14/8, 2022 at 11:58 Comment(0)
V
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.

Virescence answered 3/12, 2020 at 6:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.