在“react-hook-form”中使用对象作为值

Kon*_*owy 3 typescript reactjs react-hook-form

描述

我有一个使用对象作为值的组件。

我想使用这个组件react-hook-form

问题是react-hook-form认为我的对象是嵌套表单控件

设置

这只是一个例子。

范围日期选择器是这种行为的常见用例

代码笔示例

组件接受的值:

type ComponentValue = {
  a: string;
  b: string;
}
Run Code Online (Sandbox Code Playgroud)

组件:

const Component = ({ value, onChange }: { value: ComponentValue, onChange: (value: ComponentValue) => void }) => {
  return (
    <input value={value.a} onChange={e => onChange({ a: e.target.value, b: (Math.random() * 100 | 0).toString() }) } />
  )
}
Run Code Online (Sandbox Code Playgroud)

表格值

type FormValues = {
  someField: ComponentValue;
  // other fields
};
Run Code Online (Sandbox Code Playgroud)

默认值:

const defaultValues = {
  someField: {
    a: 'Default a',
    b: 'Default b'
  },
  // other fields
};
Run Code Online (Sandbox Code Playgroud)

useForm用法:

const {
  register,
  handleSubmit,
  formState: { errors },
  control,
} = useForm<FormValues>({
  defaultValues,
});
Run Code Online (Sandbox Code Playgroud)

问题

将鼠标悬停在(或尝试使用)上errors会显示类型:

const errors: {
  someField?: {
    a?: FieldError | undefined;
    b?: FieldError | undefined;
  } | undefined;
  // other fields
}
Run Code Online (Sandbox Code Playgroud)

但我希望它是:

const errors: {
  someField?: FieldError | undefined;
  // other fields
}
Run Code Online (Sandbox Code Playgroud)

概括

我可以以某种方式强制react-hook-form将我的对象视为值而不是嵌套表单字段吗?

pom*_*421 7

如果您想在同一组件中组合 2 个输入,您可以尝试使用控制器的方法。

export default function App() {
  const { control, handleSubmit, watch } = useForm({
    defaultValues: {
      travel: {
        from: "paris",
        to: "london"
      }
    }
  });

  const onSubmit = (data) => {
    console.log("dans onSubmit", JSON.stringify(data, null, 2));
  };

  return (
    <>
      <h1>Travel</h1>

      <form
        onSubmit={handleSubmit(onSubmit)}
        style={{ display: "flex", flexDirection: "column", maxWidth: 600 }}
        noValidate
      >
        <TravelPicker control={control} />

        <input type="submit" />
        <pre>{JSON.stringify(watch(), null, 2)}</pre>
      </form>
    </>
  );
Run Code Online (Sandbox Code Playgroud)

该组件有一个控制属性,能够注册 2 个输入:

const TravelPicker = ({ control }) => {
  return (
    <>
      <label>
        From
        <Controller
          name="travel.from"
          control={control}
          render={({ field: { onChange, value, name } }) => (
            <input name={name} value={value} onChange={(e) => onChange(e)} />
          )}
        />
      </label>
      <label>
        To
        <Controller
          name="travel.to"
          control={control}
          render={({ field: { onChange, value, name } }) => (
            <input name={name} value={value} onChange={(e) => onChange(e)} />
          )}
        />
      </label>
    </>
  );
};
Run Code Online (Sandbox Code Playgroud)

错误对象具有与表单输入相同的结构。

请参阅此沙箱以获取功能示例。

RHF 的创建者似乎在这里指出,您也可以只使用一个组件来处理 2 个输入。

  • 这是非常粗鲁的。很抱歉试图帮助你... (8认同)