使用 Controller 时,react-hook-form 不会触发 onSubmit

react-hook-form not triggering onSubmit when using Controller

我有以下表格:

      <form onSubmit={handleSubmit(onSubmit)}>
        <Controller
          name="voucherPrice"
          control={control}
          defaultValue={false}
          rules={{ required: true }}
          render={({ field: { onChange, value, ref } }) => (
            <Input {...field} onChange={(ev) => handlePriceInputChange(ev)} value={price} type="number" innerRef={ref} />
          )}
        />

        <p>{errors.voucherPrice?.message}</p>

        <Button
          variant="contained"
          sx={{ mt: 1, mr: 1 }}
          type="submit"
        >
          {"Continue"}
        </Button>
      </form>

并使用此配置:

function PriceSelection(props) {
  const {
    register,
    handleSubmit,
    control,
    formState: { errors },
  } = useForm({
    resolver: yupResolver(schema),
  });
  const onSubmit = (data) => {
    console.log("does not work?", data);
  };

  const classes = useStylesPriceSelection();
  const [selected, setSelected] = useState(false);
  const [price, setPrice] = useState("");


  const handlePriceInputChange = (ev) => {
    console.log("change", price);
    setPrice(parseInt(ev.target.value));
  };



当我按下提交按钮时函数onSubmit没有触发。此外,我希望输入字段默认由状态 price 填充,当我按下提交按钮时,它的值将与函数 onSubmit 上的参数 data 一起发送。

您将 useStatereact-hook-form 混合使用并且未更新 react-hook-form 的内部表单状态。您不需要为您的字段声明 useState

在您的示例中,您正在从 <Controller />field 对象中析构 onChange,但您从未将其用于 <Input /> 组件。因此 react-hook-form 无法更新它的表单状态。当您将字段设置为必填时,onSubmit 回调将不会被触发,因为 react-hook-form 永远不会收到它的更新或值。

正确的方法是:

<Controller
  name="voucherPrice"
  control={control}
  rules={{ required: true }}
  render={({ field: { ref, onChange, value, ...field } }) => (
    <Input {...field} onChange={onChange} value={value} type="number" innerRef={ref} />
  )}
/>

或更短:

<Controller
  name="voucherPrice"
  control={control}
  rules={{ required: true }}
  render={({ field: { ref, ...field } }) => (
    <Input {...field} type="number" innerRef={ref} />
  )}
/>

更新

如果您需要访问 <Controller /> 之外的值,您应该使用 react-hook-formwatch 方法。这将允许您订阅 voucherPrice 字段的最新值并在您的组件中使用它 -> Docs

如果您想以编程方式设置或更新值,您可以使用 react-hook-form -> Docs

中的 setValue 方法
const { control, handleSubmit, watch, setValue } = useForm();

const voucherPrice = watch("voucherPrice");

const onButtonClick = () => {
  setValue("voucherPrice", <newValue>);
}

如果您确实需要一个单独的 useState 作为您的值,并且想要将其额外更新到您的 react-hook-form 字段更新,您可以执行以下操作:

<Controller
  name="voucherPrice"
  control={control}
  rules={{ required: true }}
  render={({ field: { ref, onChange, value, ...field } }) => (
    <Input
      {...field}
      onChange={(v) => {
        onChange(v);
        handlePriceInputChange(v);
      }}
      value={value}
      type="number"
      innerRef={ref}
    />
  )}
/>

但我建议只使用 react-hook-form 解决方案,因为它具有管理表单状态所需的所有功能。