仅在触摸时将 react-hook-form 设置为脏

react-hook-form set to dirty when only touched

警告:我是 Javascript/React/react-hook-form 的新手,所以这可能是显而易见的事情,但是当我对表单中的字段使用非字符串默认值时,一旦字段被标记为脏被触摸并且没有任何字段内容被更改。

例如;

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);

代码沙盒linkhttps://codesandbox.io/s/react-hook-form-formstate-dirty-touched-submitted-0rcrj?file=/src/index.js

单击“年龄”字段,然后单击任何其他字段,而不进行任何更改,标记脏标记。

我猜他的原因是因为表单将所有内容都视为字符串,因此在 Age 字段的情况下 30 !== "30" 因此即使在 UI ?

如果我将默认值更改为年龄:“30”,则表单不会变脏,所以它似乎可以确认。

我正在尝试将脏标志用于 enable/disable 提交按钮,但这个问题破坏了它。

有什么办法解决这个问题吗?别人是怎么处理的?

这是一个非常有趣的问题,我认为你对原因的理解是正确的。

解决方法是使用 <Controller> 或手动 register 字段并使用 parseInt.

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