javascript 在react-hook-form中有条件地设置默认值

ecfdbz9o  于 5个月前  发布在  Java
关注(0)|答案(1)|浏览(55)

背景:

我有一个很长的复杂表单,使用rhf(react-hook-form)创建了深度嵌套的对象。我想在表单顶部提供一个复选框,用于切换字段中的默认值以帮助用户。

问题

通过使用rhf,我能够使用reset方法填充defaultValues,但现在的问题是,一旦我用defaultValues调用reset方法,如果我提供一个空对象,我就不能使用reset取消设置值。

我尝试过的事

我试过使用setValue方法,但它一次只取消一个字段,而且它需要递归来为深度嵌套的对象设置值。

验证码

这里有一个我正在尝试做的非常小的例子。

import React, { useState, useEffect } from "react";
import ReactDOM from "react-dom";
import { useForm } from "react-hook-form";

const defaultValues = { name: `John Doe` };

const Form = () => {
  const [useDefaultValues, setUseDefaultValues] = useState(false);
  const { register, handleSubmit, reset } = useForm();

  useEffect(() => {
    if (useDefaultValues) {
      reset(defaultValues);
    } else {
      reset({}, { keepValues: false, keepDefaultValues: false });
    }
  }, [useDefaultValues]);

  return (
    <>
      <label>
        <input
          type="checkbox"
          value={useDefaultValues}
          onChange={() => setUseDefaultValues((prev) => !prev)}
        />
        Use Default values
      </label>
      <form onSubmit={handleSubmit}>
        <div>
          <label>Name</label>
          <input type="text" name="name" {...register("name")} />
        </div>
        <input type="submit" />
      </form>
    </>
  );
};

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

字符串
Codesandbox:https://codesandbox.io/p/sandbox/react-hook-form-reset-form-forked-sxmy8q?file=%2Fsrc%2Findex.js%3A1%2C1-42%2C1
请注意,取消设置defaultValues不会再次清空表单

lyr7nygr

lyr7nygr1#

您的表单需要有3个状态。第一个包含default values。第二个需要有empty value(实际重置)。第三个需要有actual(current) values,这将由react钩子表单处理。

重置表单值的可选对象,建议提供完整的defaultValues。Source
您的代码的解决方案:

import React, { useState, useEffect } from "react";
import ReactDOM from "react-dom";
import { useForm } from "react-hook-form";

const defaultValues = { name: `John Doe` }; // your own default values

const Form = () => {
  const [useDefaultValues, setUseDefaultValues] = useState(false);
  const { register, handleSubmit, reset } = useForm({
    defaultValues: { name: `` },
  }); // actual empty defaul values, you can provide here

  useEffect(() => {
    if (useDefaultValues) {
      reset(defaultValues, { keepValues: false, keepDefaultValues: true }); // reset to defaultValues provided above
    } else {
      reset(); // reset to actual empty defaul values
    }
  }, [useDefaultValues]);

  return (
    <>
      <label>
        <input
          type="checkbox"
          value={useDefaultValues}
          onChange={() => setUseDefaultValues((prev) => !prev)}
        />
        Use Default values
      </label>
      <form onSubmit={handleSubmit}>
        <div>
          <label>Name</label>
          <input type="text" name="name" {...register("name")} />
        </div>
        <input type="submit" />
      </form>
    </>
  );
};

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

字符串

keepValues(true):

表单输入值将保持不变。假设我们将name更改为'abc',然后我们调用

reset(newValues, { keepValues: true });


表单仍然会有旧的值。这里给出的newValues不会有任何效果。
另一方面,如果我们有keepValues(false),则值将等于reset函数中提供的newValues,否则(如果提供空对象),它将成为默认值。

keepDefaultValues(true):

重置函数中给出的表单值成为默认值。为了识别表单状态的任何变化,我们使用isDirty。如果我们有keepDefaultValues(true)isDirty将比较默认值与当前表单值,以判断表单状态是否发生了变化。
另一方面,如果我们有keepDefaultValues(false),则isDirty将重置函数中的新给定值与当前表单值进行比较,以判断表单状态是否已更改。
简单地说,除了这个用例之外,如果我们想通过使用keepDefaultValues(true)来保持默认值与我们在开始时提供的值相同,keepDefaultValues函数可能很有用。

相关问题