react-hook-form 的 DefaultValues 未将值设置为 React JS 中的输入字段

Posted

技术标签:

【中文标题】react-hook-form 的 DefaultValues 未将值设置为 React JS 中的输入字段【英文标题】:DefaultValues of react-hook-form is not setting the values to the Input fields in React JS 【发布时间】:2021-01-26 02:56:57 【问题描述】:

我想使用react-hook-form 在输入字段中提供默认值。首先,我从 API 端点检索用户数据,然后将状态 users 设置为该用户数据。然后我将状态users 传递给useForm()defaultValues

import React,  useState, useEffect  from "react";
import  useForm  from "react-hook-form";
import axios from "axios";

function LoginFile() 
  const [users, setUsers] = useState(null);

  useEffect(() => 
    axios
      .get("http://localhost:4000/users/1")
      .then((res) => setUsers(res.data));
  , []);

  useEffect(() => 
    console.log(users);
  , [users]);

  const  register, handleSubmit, errors  = useForm(
    defaultValues: users,
  );
 return (
    <div>
      <form onSubmit=handleSubmit(onSubmit)>
        Email <input type="email" name="email" ref=register /><br />
        firstname <input name="firstname" ref=register /><br/>
        <input type="submit" />
      </form>
    </div>
 );

export default LoginFile;

我按照上面的代码做了,但没有按预期工作。所有输入字段仍为空。我想在表单的输入字段中有一些默认值。

【问题讨论】:

【参考方案1】:

问题是在第一次渲染时,usersuseState 钩子的初始值,即null。该值仅在axios.get() 请求完成后发生变化,即初始渲染之后。这意味着传递给useForm 的默认值是null

documentation for defaultValues 表示如下:

defaultValues 在自定义挂钩内在第一次渲染时缓存。如果你想重置defaultValues,你应该使用reset api。

因此,您只需使用reset 将表单手动重置为您获取的值。 reset 的文档说明如下:

您需要将defaultValues 传递给useForm 才能将reset 传递给Controller 组件的值。

但是,从文档中不清楚 null 是否足以作为默认值,或者您是否需要为每个输入传递一个包含字段的适当对象。为了安全起见,我们假设是后者。

执行此操作的代码如下所示:

function LoginFile() 
  const [users, setUsers] = useState( email: "", firstname: "" );

  const  register, handleSubmit, errors, reset  = useForm(
    defaultValues: users,
  );

  useEffect(() => 
    axios.get("http://localhost:4000/users/1").then((res) => 
      setUsers(res.data);
      reset(res.data);
    );
  , [reset]);

  useEffect(() => 
    console.log(users);
  , [users]);

  return (
    <div>
      <form onSubmit=handleSubmit(onSubmit)>
        Email <input type="email" name="email" ref=register />
        <br />
        firstname <input name="firstname" ref=register />
        <br />
        <input type="submit" />
      </form>
    </div>
  );

此外,如果 useState 挂钩的唯一原因是存储 defaultValues 的值,则根本不需要它,可以将代码清理为:

function LoginFile() 
  const  register, handleSubmit, errors, reset  = useForm(
    defaultValues:  email: "", firstname: "" ,
  );

  useEffect(() => 
    axios.get("http://localhost:4000/users/1").then((res) => 
      reset(res.data);
    );
  , [reset]);

  return (
    <div>
      <form onSubmit=handleSubmit(onSubmit)>
        Email <input type="email" name="email" ref=register />
        <br />
        firstname <input name="firstname" ref=register />
        <br />
        <input type="submit" />
      </form>
    </div>
  );

【讨论】:

reset(res.data) 是否会将 defaultValue 重置为 API 用户数据,例如 email: "subro@gg.com", firstname: "subrato"?我问这个 bcz 我的心态是重置意味着清空输入字段。 reset 的文档说:“您可以将值作为可选参数传递,以将表单重置为分配的默认值。”. 我的用户数据中有id 键。当我们在 useForm 中定义它们时,id 的默认值是什么? id: 0, email; "", firstname:"" 可以吗?我正在使用您的第一种方法。 是的,这项工作。当我将状态设置为null 时,我注意到我喜欢分享的一件事它向我显示了一个类似cannot read property of "email" which is null' 的错误,但是当我将状态设置为[] 时,它会向输入字段显示空值跨度> @cbr 谢谢你,你是救世主【参考方案2】:

这绝对有效。使用重置 API 和 UseEffect。

从空字符串作为默认值开始,并通过重置将它们更新为效果。这是我的代码。在这里也使用带有 Ionic 的 TypeScript...

const  control: editControl, handleSubmit: editSubmit, reset  = useForm<EditFormType>(
      defaultValues: 
         question: "",
         optionA: "",
         optionB: "",
         optionC: "",
         optionD: "",
      
   );

   useEffect(() => 
      let defaults =
         question: editQuestion?.body,
         optionA: editQuestion?.options[0].body,
         optionB: editQuestion?.options[1].body,
         optionC: editQuestion?.options[2].body,
         optionD: editQuestion?.options[3].body,
      
      reset(defaults)
   , [editQuestion, reset])

【讨论】:

这个答案更容易解决我的问题,因为它没有其他答案的所有额外噪音。

以上是关于react-hook-form 的 DefaultValues 未将值设置为 React JS 中的输入字段的主要内容,如果未能解决你的问题,请参考以下文章

React-hook-form 输入字段匹配验证最佳实践

react-hook-form 中的寄存器是啥类型?

react-hook-form使用

如果输入在材料 ui 对话框中,react-hook-form 的 setValue 方法不起作用

使用 reactstrap 从 react-hook-form 访问错误

带有 react-hook-form 的单选按钮