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

新手上路,请多包涵

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

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

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

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

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

原文由 Sam 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.2k
2 个回答

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

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

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

您有两种选择:

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

原文由 Domino987 发布,翻译遵循 CC BY-SA 4.0 许可协议

对于外部控制组件

如果您使用的是 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>
  );
}

如果您使用的是 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>
  );
}

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

原文由 Bill 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进