简体   繁体   中英

react-hook-form set to dirty when only touched

Caveat: I'm brand new to Javascript/React/react-hook-form so this may be something obvious but when I use non-string default values for fields in a form, the form gets marked as dirty as soon as the field is touched and without any field content being changed.

For example;

import ReactDOM from "react-dom";
import { useForm } from "react-hook-form";

import "./styles.css";

export default function Form() {
  //Declare default values
  const defaults = {
    Firstname: "Fred",
    Lastname: "Bloggs",
    Age: 30
  };

  const { register, handleSubmit, formState } = useForm({
    mode: "onChange",
    defaultValues: { ...defaults }
  });
  const onSubmit = data => {
    alert(JSON.stringify(data));
  };

  // make sure to read state before render to subscribe to the state update (Proxy).
  const { dirtyFields } = formState;

  // check your dev console, it's a Set
  console.log(dirtyFields);

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <label>Full name</label>
      <input type="text" name="Firstname" ref={register({ required: true })} />

      <label>Last name</label>
      <input type="text" name="Lastname" ref={register({ required: true })} />

      <label>Age</label>
      <input type="number" name="Age" ref={register} />

      <pre>{JSON.stringify(formState, null, 2)}</pre>

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

const rootElement = document.getElementById("root");
ReactDOM.render(<Form />, rootElement);

CodeSandbox link https://codesandbox.io/s/react-hook-form-formstate-dirty-touched-submitted-0rcrj?file=/src/index.js

Clicking in the Age field and then any another field, without making any changes, marks the dirty flag.

I'm guessing that his is because the form treats everything as a string and so in the case of the Age field 30?== "30" and so the form becomes dirty even though nothing was changed in the UI ?

If I change the default to Age: "30" then the form does not become dirty so it seems to confirm it.

I'm trying to use the dirty flag to enable/disable a submit button but this issue is breaking that.

Is there any way around this? How do others handle it?

This is a very interesting catch and I think you are correct about the reason.

A workaround would be to use a <Controller> or to manually register the field and apply a transformation with parseInt .

<Controller
    name="Age"
    control={control}
    type="number"
    as="input"
    onChange={([event]) => parseInt(event.target.value)}
/>

编辑 React Hook 表单 - formState (Dirty, Touched, Submitted)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM