【问题标题】:DefaultValues of react-hook-form is not setting the values to the Input fields in React JSreact-hook-form 的 DefaultValues 未将值设置为 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;

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

【问题讨论】:

    标签: reactjs react-hook-form


    【解决方案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])

    【讨论】:

    • 这个答案更容易解决我的问题,因为它没有其他答案的所有额外噪音。
    猜你喜欢
    • 2023-01-12
    • 2021-12-05
    • 2022-07-30
    • 2023-03-17
    • 1970-01-01
    • 2021-03-29
    • 2021-12-09
    • 2021-01-20
    • 2020-03-08
    相关资源
    最近更新 更多