TanStackT
TanStack7mo ago
11 replies
full-green

how to switch to onChange validation after doing onBlur validation for better user experience ?

this code works. but if the user encounters an error and goes back to fix an input, the user doesnt know when the error was fixed.
since it uses onBlur to check. I dont want onChange to be done in the start either ( immediately gets an error when the user starts typing that the email is invalid )
so how could i initially validate with an onBlur ( so user doesn't get an error till they type it out and switches to the next field )
but if they do get an error, i want the user to know when the error was fixed while the user types it out. ( onChange )
react-hook-form does this automatically. maybe i'm missing something.
but i love form composition in tanstack. main reason why i use it.

const form = useAppForm({
    defaultValues: {
      email: "",
      password: "",
    },
    onSubmit: async (data) => {
      await new Promise(r => setTimeout(r, 2000));
      let res = server.auth.webUserLogin({ email: data.value.email, password: data.value.password })
      console.log(res);
    }
  })
  return <div className='w-full h-full! flex flex-col justify-center items-center'>
    <Card className='w-full max-w-md'>
      <CardContent>
        <div className='flex flex-col space-y-5 p-5'>
          <h4 className="text-center mb-5 scroll-m-20 text-xl font-semibold tracking-tight">
            {t("auth_login")}
          </h4>

          <form.AppField
            name="email"
            validators={{ onBlur: z.string().email({ message: t("email_valid") }).min(1, t("field_required", t("email"))) }}
            children={(field) => <field.TextField label="Email" />}
          />
          <form.AppField
            name="password"
            validators={{ onBlur: z.string().min(1, t("field_required", t("password"))) }}
            children={(field) => <field.PasswordField label="Password" />}
          />
          <form.AppForm>
            <form.SubmitButton label={t("login")} />
          </form.AppForm>
        </div>
      </CardContent>
    </Card>
  </div>
Was this page helpful?