使用 React-Hook-Form 填充表单时遇到问题

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

所以我一直在尝试使用react-hook-form创建一个多步骤表单,我成功地做到了这一点,作为创造价值的一种方式。

但是当涉及到更新它们时。有点难。它确实有效,因为它确实获取数据来填充表单。它确实成功更新了我的数据库上的表。但它似乎没有为输入提供默认值。

我尝试使用 useForm() Hook 的 defaultValues{} 选项,但由于它的值是从后端获取的,因此需要重置。

然而,当我实施它们时......什么也没有发生。数据就在那里,我已经测试过了。它确实会重置,但在 .tsx 文件中......什么也没有。

即使我 console.log(watch()) 也只出现空字符串或空值。我尝试过强制将值作为道具,但它看起来很糟糕,我不认为这是处理它的方法。特别是因为存在 defaultValues 选项。

也许错误是因为我使用的是多步骤表单,但我不明白为什么它不起作用。

我仍在努力学习 React。因此,我们非常感谢任何有关如何解决此问题以及代码本身的反馈或指导。

这些是相关的代码片段:

//EditarDentista.tsx:这是保存 apiQueries 并处理大部分逻辑的主页:

const EditarDentista = () => {
  const { idDentista } = useParams();

  const { data: dentista, isLoading: fetching } = useQuery(
    ["fetchDentista", idDentista], // Include idDentista in the query key
    () => apiClient.getSingleDentista(idDentista as string),
    { retry: 0 }
  );

  const { mutate, isLoading } = useMutation(
    ({ idDentista, data }: { idDentista: string; data: EditarDentistaFormType }) =>
      apiClient.updateDentista(idDentista, data),
    {
      onSuccess: () => {
        alert("Success");
      },
      onError: () => {
        alert("Error:");
      },
    }
  );

  const onSave = (data: EditarDentistaFormType) => {
    if (idDentista) {
      mutate({ idDentista, data });
    } else {
      <Navigate to={'/'} />; // TODO: Improve Error Handler
    }
  };

  return (
    <ManageEditarDentista isEditing={isLoading} onSave={onSave} dentista={dentista} isFetching={fetching} />
  );
};

//将保存状态的管理器、formProvider 以及使用 fetchedValues

const ManageEditarDentista = ({ onSave, isEditing, dentista, isFetching }: ManageEditarDentistaProps) => {
    const formMethods = useForm<EditarDentistaFormType>();
    const { reset, handleSubmit } = formMethods;
    const [paginaActual, setPaginaActual] = useState(0);

    console.log(dentista, 1);
    useEffect(() => {
        if (dentista) {
            reset({
                nombre: dentista.nombre,
                apPaterno: dentista.apPaterno,
                apMaterno: dentista.apMaterno,
                correo: dentista.correo,
                carnet: dentista.carnet,
                fechaNacimiento: dentista.fechaNacimiento,
                telefono: dentista.telefono,
                especialidad: dentista.especialidad
            });
        }
    }, [dentista, reset]);
    console.log(dentista, 2);
    if (isFetching) {
        return (
            <div className="w-full h-screen flex items-center justify-center">
                <TailSpin
                    visible={true}
                    height="100%"
                    width="100%"
                    color="#D10056"
                    ariaLabel="tail-spin-loading"
                    radius="1"
                    wrapperStyle={{}}
                    wrapperClass=""
                />
            </div>
        );
    }

    const onSubmit = handleSubmit((data: EditarDentistaFormType) => {
        if (paginaActual !== 1) {
            setPaginaActual(prev => prev + 1);
        } else {
            onSave(data);
        }
    });

    return (
        <div className="w-full h-full flex items-center justify-center">
            <FormProvider {...formMethods}>
                <form className="w-[60vw] h-[60vh] bg-slate-400" onSubmit={onSubmit}>
                    {paginaActual === 0 && <Pagina1FormularioEditar />}
                    {paginaActual === 1 && <Pagina2FormularioEditarDentista />}
                    {paginaActual == 1 && <button onClick={() => setPaginaActual(paginaActual - 1)}>Back</button>}
                    <button
                        disabled={isEditing}
                        className="py-1 px-2 disabled:bg-slate-800 bg-slate-500 hover:bg-slate-300"
                        type="submit"
                    >
                        {isEditing ? "Loading..." : paginaActual === 1 ? "Submit" : "Next"}
                    </button>
                </form>
            </FormProvider>
        </div>
    );
}

//以其中一页为例:

    const { register, formState: { errors }, watch } = useFormContext<EditarDentistaFormType>()
    console.log(watch());
    return (
        <div className="flex flex-col gap-4">
            <div className=" bg-slate-500 flex justify-center items-center h-5">
                Informacion Personal:
            </div>
            <label className="text-gray-700 text-sm font-bold flex-1 mx-10 ">
                Nombre:
                <input type="text"
                    className="border border-blue-500 w-full py-1 px-2 font-normal"
                    {...register("nombre", { required: "This field is required" })} />
            </label>
            <label>
                Apellido Paterno:
                <input type="text" {...register("apPaterno", { required: "This field is required" })} />
                {errors.apPaterno && <span className="text-sm text-red-500 font-semibold">{errors.apPaterno.message}</span>}
            </label>
            <label>
                Apellido Materno:
                <input type="text" {...register("apMaterno", { required: "This field is required" })} />
                {errors.apMaterno && <span className="text-sm text-red-500 font-semibold">{errors.apMaterno.message}</span>}
            </label>
            <label>
                Carnet:
                <input type="text"
                    {...register("carnet", { required: "This field is required" })} />
                {errors.carnet && <span className="text-sm text-red-500 font-semibold">{errors.carnet.message}</span>}
            </label>
        </div>
    )
}

它是功能代码......我认为......因为它确实更新。但如果没有实际看到当前的数据更新就真的很麻烦了。

无论如何,我感谢您花时间阅读我的臭代码,正如我所说,非常欢迎任何反馈或指导。谢谢您的宝贵时间!

reactjs typescript react-hooks frontend react-hook-form
1个回答
0
投票

尝试

values
useForm

道具

values 属性将对更改做出反应并更新表单值,这在您的表单需要通过外部状态或服务器数据更新时非常有用。 -反应钩子形式

https://react-hook-form.com/docs/useform#defaultValues

// set default value sync
function App({ values }) {
  useForm({
    values, // will get updated when values props updates
  })
}

function App() {
  const values = useFetch("/api")

  useForm({
    defaultValues: {
      firstName: "",
      lastName: "",
    },
    values, // will get updated once values returns
  })
}
© www.soinside.com 2019 - 2024. All rights reserved.