首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >接触字段会导致react-hook-form变脏

接触字段会导致react-hook-form变脏
EN

Stack Overflow用户
提问于 2020-11-22 11:34:31
回答 1查看 2.6K关注 0票数 0

我对react-hook-form有一个问题,简单地“触摸”一个字段(点击它,然后在其他地方点击)就会导致formState.isDirty为真。我已经在这个代码框中重现了这个问题:

https://codesandbox.io/s/react-hook-form-dirty-by-touch-p8x6j

我从服务器加载一条记录并调用reset(),以便将其视为新的基线,这可能是导致问题的原因。但是,作为一个动态表单,我需要从服务器检索要加载到表单中的对象,所以我看不到解决这个问题的办法。我所希望的是,只要值没有实际改变,formState.isDirty就保持为假。

对于更复杂的组件(比如react-select),我自己调用register(‘无论什么’)就没有这个问题,只有我使用ref={register}的原生超文本标记语言输入才有这个问题。

代码语言:javascript
运行
复制
import React, { useState, useEffect } from "react";
import "./styles.css";
import { useForm } from "react-hook-form";
import { yupResolver } from "@hookform/resolvers/yup";
import * as yup from "yup";

export default function App() {
  interface MyObject {
    testing: string;
    id: number;
  }

  const blankObject: MyObject = {
    testing: "Default value",
    id: 0
  };

  const [obj, setObj] = useState(blankObject);

  const schema = yup.object().shape({
    testing: yup.string().max(40)
  });

  const { register, handleSubmit, formState, reset, errors } = useForm<
    MyObject
  >({
    resolver: yupResolver(schema),
    defaultValues: blankObject
  });

  useEffect(() => {
    setTimeout(() => {
      const newObj = {
        testing: "Pretend this came from the server",
        id: 123
      };
      setObj(newObj);
      reset(newObj);
    }, 2000);
  }, [reset]);

  const onSubmit = (data: MyObject) => {
    alert(JSON.stringify(data));
  };

  const onReset = () => {
    reset();
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      {obj.id === 0 ? (
        <p>Please wait...</p>
      ) : (
        <div>
          <p>ID: {obj.id}</p>
          <label>Enter text: </label>
          <input
            type="text"
            name="testing"
            ref={register}
            autoComplete="off"
            style={{ width: "50%" }}
            defaultValue={obj.testing}
          />
          {errors.testing && (
            <div style={{ color: "#ff0000" }}>{errors.testing?.message}</div>
          )}

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

          <input type="submit" />
          <input type="button" value="reset" onClick={onReset} />
        </div>
      )}
    </form>
  );
}

我也许可以去掉ref={register}并手动处理注册,但这样做似乎有点脱离了反应钩子表单的意义。

谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-11-23 07:30:56

React钩子表单如何验证表单是否脏是基于深度比较defaultValues

下面是示例的defaultValues:(在重置之后)

代码语言:javascript
运行
复制
const newObj = {
  testing: "Pretend this came from the server",
  id: 123
};

但是,没有像id这样的字段在钩子表单中注册。因此,比较也将是不匹配的,因为缺少id

下面的示例可能会为您提供更好的上下文。

https://codesandbox.io/s/snowy-bush-jjcqk?file=/src/App.tsx

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64950422

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档