typescript 有没有一种方法可以使用Shadcn Form & Zod来获取onChange的表单值?

bq3bfh9z  于 2023-11-20  发布在  TypeScript
关注(0)|答案(1)|浏览(156)

我已经实现了一个使用zod进行客户端验证的表单,我还想添加一个密码强度显示,为此我决定尝试react-password-strength-bar。
这个功能很简单,你只需要渲染PasswordStrengthBar并将密码值作为 prop 传入:

import PasswordStrengthBar from "react-password-strength-bar";

<PasswordStrengthBar password={pass} />

字符串
在尝试时,我注意到我不能对Input字段使用onChange事件侦听器,因为显然它已经被使用了。ref也是如此,我会使用useEffect,它会在每次输入值更改时触发。
我发现我可以使用form.getValues(“password”)来获取值。使用form函数作为依赖项感觉不对,然后我会将其用作PasswordStrengthBar的值。我还尝试将form放置在useEffect中,但似乎它不会随着输入的变化而更新。
有没有人知道我该怎么做?
完整代码:

"use client";

import { zodResolver } from "@hookform/resolvers/zod";
import * as z from "zod";
import { useForm } from "react-hook-form";
import { useContext, useEffect, useState } from "react";
import NotificationContext from "@/lib/context/notification-context";
import defaultNotification from "@/lib/locale/default-notification";
import PasswordStrengthBar from "react-password-strength-bar";
import { authFormSchema } from "@/lib/formSchema";
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import SubmitButton from "../ui/custom-ui/submit-btn";

export default function AuthForm() {
  const notifCtx = useContext(NotificationContext);
  const [pass, setPass] = useState<string>("");

  const form = useForm<z.infer<typeof authFormSchema>>({
    resolver: zodResolver(authFormSchema),
    defaultValues: { email: "", password: "" }
  });
  const isLoading = form.formState.isSubmitting;

  async function onSubmit(values: z.infer<typeof authFormSchema>) {
    // ✅ This will be type-safe and validated.
    notifCtx.setNotification(defaultNotification.pending);

    const res = await fetch("/api/auth/signup", {
      method: "POST",
      body: JSON.stringify({ ...values })
    });
    const { err, msg } = await res.json();

    notifCtx.setNotification(defaultNotification[err ? "error" : "success"](msg));
    !err && form.reset();
    return;
  }
  useEffect(() => {
    setPass(form.getValues("password"));
  }, [form]);

  return (
    <Form {...form}>
      <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-2">
        <FormField
          control={form.control}
          name="email"
          render={({ field }) => (
            <FormItem>
              <FormLabel>Email</FormLabel>
              <FormControl>
                <Input placeholder="[email protected]" {...field} />
              </FormControl>
              <FormMessage />
            </FormItem>
          )}
        />
        <FormField
          control={form.control}
          name="password"
          render={({ field }) => (
            <FormItem>
              <FormLabel className="">Password</FormLabel>
              <FormControl>
                <Input placeholder="password123" type="password" {...field} />
              </FormControl>
              <FormMessage />
            </FormItem>
          )}
        />

        <PasswordStrengthBar password={pass} />

        <div className="">
          <SubmitButton
            className="w-full my-4 dark:bg-white dark:hover:bg-primary dark:text-black dark:hover:text-white"
            isLoading={isLoading}
            text="Sign up"
          />
        </div>
      </form>
    </Form>
  );
}

a8jjtwal

a8jjtwal1#

解决:我忘了你可以使用onChangeCapture,因为它不包含任何子元素来触发更多的动作。

<Input placeholder="password123" onChangeCapture={e => setPass(e.currentTarget.value)} type="password" {...field} />

字符串

相关问题