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

Sam*_*Sam 12 reactjs material-ui react-hook-form

我尝试使用 react-hook-form 来验证输入。但是我发现如果输入被放置在 Material UI 的对话框组件中,react-hook-formsetValue不会按预期工作,但是当我删除 Dialog 组件时它可以工作。我猜原因是该值是在组件安装之前设置的,但仍然找不到解决方案。

该值将从服务器检索,所以我不能使用 react-hook-form 的defaultValues.

https://codesandbox.io/s/react-hook-form-material-ui-twbbw

我曾尝试使用useState来控制输入值,但还有一个问题。清除输入后,点击提交按钮,出现错误提示,我输入的第一个字母不显示。

https://codesandbox.io/s/react-hook-form-material-ui-ve2en

Dom*_*987 11

问题在于注册功能。在调用 Textfield 的 ref 之后,您正在使用 register 注册 Textfield。

setValue在初始渲染之后调用 useEffect 将名称设置为 123 。如果open为 true,则在 useEffect 之后呈现对话框内容。内容渲染完成后,会调用带有 register 的 ref,并将 Textfield(此处undefined)的默认值设置为 name 的值。

这就是为什么 Textfield 的值显示为 "" 的原因。您需要在调用 render 和 ref 回调后调用 setValue,以便该值保持不变。

您有两种选择:

  1. 更改setTimeout后使用异步延迟(或承诺)在useEffect 中设置值 async open。因此,如果您添加open到 useEffect 依赖项数组并设置值 async,它就可以工作。这是一个沙箱
  2. 设置 Textfield 的默认值或使用 将默认值添加到钩子useForm({defaultValues: {name: '123}})


Bru*_*uce 5

对于外部受控组件

如果您使用的是 V3,我建议您使用react-hook-form-input https://github.com/react-hook-form/react-hook-form-input

import React from 'react';
import useForm from 'react-hook-form';
import { RHFInput } from 'react-hook-form-input';
import Select from 'react-select';

const options = [
  { value: 'chocolate', label: 'Chocolate' },
  { value: 'strawberry', label: 'Strawberry' },
];

function App() {
  const { handleSubmit, register, setValue, reset } = useForm();

  return (
    <form onSubmit={handleSubmit(data => console.log(data))}>
      <RHFInput
        as={<Select options={options} />}
        rules={{ required: true }}
        name="reactSelect"
        register={register}
        setValue={setValue}
      />
      <button type="button">Reset Form</button>
      <button>submit</button>
    </form>
  );
}
Run Code Online (Sandbox Code Playgroud)

如果您使用的是 V4,我建议您使用Controller https://react-hook-form.com/api/#Controller

import React from 'react';
import Select from 'react-select';
import { TextField } from "@material-ui/core";
import { useForm, Controller } from 'react-hook-form';

const options = [
  { value: 'chocolate', label: 'Chocolate' },
  { value: 'strawberry', label: 'Strawberry' },
  { value: 'vanilla', label: 'Vanilla' },
];

function App() {
  const { handleSubmit, control } = useForm();

  return (
    <form onSubmit={handleSubmit(data => console.log(data))}>
      <Controller
        as={<Select options={options} />}
        control={control}
        rules={{ required: true }}
        onChange={([selected]) => {
          // React Select return object instead of value for selection
          return { value: selected };
        }}
        name="reactSelect"
      />

      <Controller
        as={<TextField />}
        name="firstName"
        control={control}
      />

      <button>submit</button>
    </form>
  );
}
Run Code Online (Sandbox Code Playgroud)

包装您的受控组件并在其中收集数据的想法,同时仍然隔离外部受控组件内的重新渲染。

  • 我认为问题是何时调用 setValue,您可能应该在对话打开后调用它 (2认同)

San*_*Ali 5

setValue就我而言,我在模态中使用。它没有按预期工作。我不得不添加shouldUnregister: false进来useForm

const { errors, register, setValue, handleSubmit } = useForm({
resolver: useYupValidationResolver(CustomDomainSchema),
mode: 'all',
shouldUnregister: false,
});
Run Code Online (Sandbox Code Playgroud)

我在阅读了有关 的讨论后解决了这个问题react-hook-form。这是沙箱上的一个工作示例