Quick start

You only need a couple things to get started with RVF.

Your first form

Let's set up a really simple form with a name and email field.

By default, RVF let's the browser do most of the heavy lifting, so it must be used with a native html form element (though there is an escape hatch).

Simple form

import { useForm } from "@rvf/react";

const MyForm = () => {
  const form = useForm({
    schema: z.object({
      name: z.string().min(1),
      email: z.string().email().min(1),
    }),
    defaultValues: {
      name: "",
      email: "",
    },
  });

  return (
    <form {...form.getFormProps()}>
      <label>
        Name
        <input name="name" />
      </label>

      <label>
        Email
        <input name="email" />
      </label>

      <button type="submit">Submit</button>
    </form>
  );
};

Choose how to show your errors

Now you can access your form's validation errors using form.error("fieldName"). It's common to simply display these errors in the UI, but RVF also provides two hooks for using the native validation APIs instead. useNativeValidity and useNativeValidityForForm both display errors using setCustomValidity.

  <label>
    Name
-   <input name="name" />
+   <input name="name" aria-describedby="name-error" />
  </label>
+ {form.error("name") && (
+   <div id="name-error">{form.error("name")}</div>
+ )}

Getting a little more power

With this setup you can use many of the features of RVF. Pretty much all of the RVF features that observe the form will work now.

  • Validation
  • Listening to changes in input values
  • Observing dirty & touched states
  • etc.

Plus a couple other things like:

  • Programmatically moving focus to any field in the form
  • Modifying dirty & touched states

But what we can't do yet is to modify the form's values, either with default values or programmatically modifying the form on the fly.

Wiring up the inputs

To be able to make changes to the form's values, we need to wire up the inputs with form.getInputProps.

-   <input name="name" aria-describedby="name-error" />
+   <input
+     {...form.getInputProps("name")}
+     aria-describedby="name-error"
+   />

Next steps

That's all you really need to get started, but it isn't all RVF can do. Check out the guides or the API reference to learn more about power features like

  • Nested objects and arrays
  • Field arrays
  • Controlled components
  • Creating your own powerful, typesafe abstractions using form scopes.
  • "State mode"