如何使用React-Hook-Form使用“ SetValue”触发重新渲染?

发布于 2025-01-18 01:15:03 字数 1101 浏览 0 评论 0原文

我有一个带有选择字段的简单表单,它是 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 可以神奇地工作。当我提供一个新值时,它会按预期工作。问题(我猜)是组件没有重新渲染,所以旧值仍然显示。我不知道如何解决这个问题,文档也没有多大帮助。非常感谢任何帮助,谢谢!

I have a simple form with a select field, it's react-hook-form for validation and everything. There's a Controller which renders a Material UI Select. I would like to set the value of such select using setValue from outside the component (in the root of the form, where all controls reside).
This is the piece of code I'm using (slightly simplified not to waste too much of your time)

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>
      )
    }}
  />
);

As far as changing the value of the select, setValue works magically. When I feed a new value, it works as intended. The problem (I guess) is the component is not re-rendered, so the old value is still shown. I'm not sure how to fix this thing and docs did not help a lot. Any help is much appreciated, thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

月寒剑心 2025-01-25 01:15:03

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

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

As @knoefel said I tried setting the defaultValue="" but doesn't work for me(maybe because I am using FormProvider). So what I did is use watch instead of value

<Controller
  name='name'
  control={control}
  render={({ field: { onChange } }) => (
    <Select
      dropdownValues={dropdownValues}
      value={watch('name')}
      onChange={onChange}
    />
  )}
/>
回梦 2025-01-25 01:15:03

我认为您只是忘记将value &lt; controller/&gt; prop to &lt; muiselect/&gt;。您还必须通过defaultValue prop prop或通过useform < /代码>。

<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>
    )
  }}
/>

I think you just forgot to set the value prop of <Controller /> to your <MuiSelect />. You also have to set a defaultValue for your <Controller /> field, either via the defaultValue prop or via useForm.

<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>
    )
  }}
/>

Edit BasicSelect Material Demo (forked)

背叛残局 2025-01-25 01:15:03

这是我的代码库中的一个片段。就我而言,我只是向 MUI 的 value prop 添加了一个三元运算符。我之前的代码 value={value} 变成了 value={value ? value : ""} 并且足以强制 MUI 在每次 value 更改时重新渲染。我不完全确定为什么会这样,但如果有人知道,我很乐意受到启发。

 <Controller
      control={props.control}
      name={props.name}
      render={({ field: { onChange, value } }) => {
        return (
          <TextField
            size="small"
            fullWidth
            value={value ? value : ""}
            type="text"
            label={props.label}
            {...props.register(props.name)}
            onChange={(e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
              onChange(e);
              if (props.onAfterChange) {
                props.onAfterChange(e);
              }
            }}
          />
        );
      }}
    />

希望这有帮助!

Here's a snippet from my codebase. In my case, I simply added a ternary operator to MUI's value prop. My previous code value={value} became value={value ? value : ""} and it sufficed to force MUI to rerender on each value change. I'm not fully certain on why this works, but if anyone knows, I would love to be enlightened.

 <Controller
      control={props.control}
      name={props.name}
      render={({ field: { onChange, value } }) => {
        return (
          <TextField
            size="small"
            fullWidth
            value={value ? value : ""}
            type="text"
            label={props.label}
            {...props.register(props.name)}
            onChange={(e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
              onChange(e);
              if (props.onAfterChange) {
                props.onAfterChange(e);
              }
            }}
          />
        );
      }}
    />

Hope this helps!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文