使用react-hook-form在handleSubmit回调中设置React状态

问题描述 投票:0回答:2

我正在使用react-hook-form为客户端应用程序构建一些用户输入。

用户应该能够更新输入。然后onBlur,react-hook-form就是验证输入并更新一个react useState对象。如果验证失败,外部状态不会更新。

以下代码无法使外部状态对象在Blur上保持最新。

由于 handleSubmit() 函数是异步的,我无法设置状态。

function App() {
  const [value, setValue] = useState({
    name: "",
  });

  const { register, handleSubmit } = useForm({ mode: "onBlur" });

  return (
    <>
      {errors?.name ? <p>{errors.name.message}</p> : null}
      <label htmlFor="name">Name</label>
      <input
        {...register("name", {
          onBlur: handleSubmit((data) => {
            setValue((prev) => ({ ...prev, name: data.name }));
          }),
          minLength: { value: 2, message: "Name is too short" },
          required: { value: true, message: "Name is required" },
        })}
        id="name"
        type="text"
      />
    </>
  );
}
  • 我尝试将handleSubmit包装在async/await中 - 但这不会产生任何结果,因为handleSubmit方法只会将结果公开给回调函数。
  • react-hook-form watch() 函数上的useEffect;问题是你没有得到验证。
  • 创建我自己的同步方法来验证似乎违背了使用react-hook-form的目的。
javascript reactjs asynchronous react-hooks react-hook-form
2个回答
0
投票

更新的代码——这对你有用..我已经更新了代码。

import React, { useState } from "react";
import { useForm } from "react-hook-form";

function App() {
  const [value, setValue] = useState({
    name: "",
  });

  const {
    register,
    trigger,
    getValues,
    formState: { errors },
  } = useForm({ mode: "onBlur" });

  const handleBlur = async (fieldName) => {
    const isValid = await trigger(fieldName); // Validate the field
    if (isValid) {
      const fieldValue = getValues(fieldName); // Get the current field value
      setValue((prev) => ({ ...prev, [fieldName]: fieldValue }));
    }
  };

  return (
    <>
      {errors?.name && <p>{errors.name.message}</p>}
      <label htmlFor="name">Name</label>
      <input
        {...register("name", {
          onBlur: () => handleBlur("name"), // Call the custom blur handler
          minLength: { value: 2, message: "Name is too short" },
          required: { value: true, message: "Name is required" },
        })}
        id="name"
        type="text"
      />
    </>
  );
}


export default App;

0
投票

您的实现中的问题是由于在输入的 onBlur 事件中使用react-hook-form的handleSubmit函数引起的。 handleSubmit 专为表单提交而设计,期望处理整个表单而不是单个字段。

为了创建单独的字段并更新外部状态,我将使用react-hook-form中的触发器进行字段级验证。触发方法可以通过编程方式验证特定字段,如果验证通过,您就可以安全地更新外部状态。

我会做什么:

import { useForm } from "react-hook-form";

function App() {
  const [value, setValue] = useState({
    name: "",
  });

  const {
    register,
    trigger,
    getValues,
    formState: { errors },
  } = useForm({ mode: "onBlur" });

  const handleBlur = async () => {
    const isValid = await trigger("name"); // Trigger validation 
    if (isValid) {
      const updatedValue = getValues("name"); // Get the current value
      setValue((prev) => ({ ...prev, name: updatedValue }));
    }
  };

  return (
    <>
      {errors?.name ? <p>{errors.name.message}</p> : null}
      <label htmlFor="name">Name</label>
      <input
        {...register("name", {
          minLength: { value: 2, message: "Name is too short" },
          required: { value: true, message: "Name is required" },
        })}
        id="name"
        type="text"
        onBlur={handleBlur} 
      />
      <p>External State: {value.name}</p>
    </>
  );
}

export default App;

© www.soinside.com 2019 - 2024. All rights reserved.