【问题标题】:How to trigger re-render with `setValue` using react-hook-form?如何使用 react-hook-form 使用“setValue”触发重新渲染?
【发布时间】:2022-06-22 12:32:54
【问题描述】:

我有一个带有选择字段的简单表单,它是 react-hook-form 用于验证和所有内容。有一个 Controller 可以渲染 Material UI Select。我想使用组件外部的setValue 设置此类选择的值(在所有控件所在的表单根目录中)。
这是我正在使用的一段代码(稍微简化一下,以免浪费您太多时间)

type Props = {
  name: string;
  control: Control<any>;
  options: SelectOptions[];
};
const Select: FunctionComponent<Props> = ({
  name,
  control,
  options,
}) => (
  <Controller
    control={control}
    name={name}
    render={({ field: { onChange, value } }) => {
      return (
        <FormControl>
          <MuiSelect onChange={onChange}>
            {options.map((o) => (
              <MuiSelectItem key={o.key} value={o.value}>{o.label}</MuiSelectItem>
            ))}
          </MuiSelect>
        </FormControl>
      )
    }}
  />
);

就更改选择的值而言,setValue 可以神奇地工作。当我输入一个新值时,它会按预期工作。问题(我猜)是组件没有重新渲染,所以旧值仍然显示。我不确定如何解决这个问题,文档并没有太大帮助。非常感谢任何帮助,谢谢!

【问题讨论】:

  • 您可以使用诸如 useState() 和 useEffect() 之类的 react-hook 以便在更改特定值时重新渲染。
  • @DevProgrammer 我不知道该怎么做,因为我认为 Material UI 的组件中已经使用了一个钩子。
  • 例如。常量 { 值,setValue } = useState(""); useEffect( () => { // 在这里写你的代码 }, value);如果 value 由 setValue 设置,则会自动更新。

标签: reactjs forms select react-hook-form


【解决方案1】:

我认为您只是忘记将&lt;Controller /&gt;value 属性设置为您的&lt;MuiSelect /&gt;。您还必须通过defaultValue 属性或useForm 为您的&lt;Controller /&gt; 字段设置defaultValue

<Controller
  control={control}
  name={name}
  defaultValue=""
  render={({ field: { onChange, value } }) => {
    return (
      <FormControl>
        <MuiSelect onChange={onChange} value={value}>
          {options.map((o) => (
            <MuiSelectItem key={o.key} value={o.value}>{o.label}</MuiSelectItem>
          ))}
        </MuiSelect>
      </FormControl>
    )
  }}
/>

【讨论】:

  • 试图这样做,但它并没有解决问题。也许我错过了其他东西。
  • 您是否为&lt;Controller /&gt; 设置了默认值?我更新了我的答案并添加了一个沙盒。
  • 感谢沙盒!可能还有其他东西干扰了我的代码。奇怪,我在一个空白页面上测试这个组件。
  • 你能用整个代码更新你的问题吗?
  • 我收回我所说的话,它在传递默认值时就像一个魅力,犯了一个愚蠢的错误。谢谢!
【解决方案2】:

正如@knoefel 所说,我尝试设置defaultValue="",但对我不起作用(可能是因为我使用的是FormProvider)。所以我所做的是使用watch 而不是value

<Controller
  name='name'
  control={control}
  render={({ field: { onChange } }) => (
    <Select
      dropdownValues={dropdownValues}
      value={watch('name')}
      onChange={onChange}
    />
  )}
/>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-17
    • 2021-07-28
    • 2023-01-31
    • 2023-03-08
    • 2020-06-12
    相关资源
    最近更新 更多