skip to content
Samuel Edwin's Website

React Hook Form Tutorial - Prefilling Form Fields

/ 2 min read

There are some use cases of when we want a form to be prefilled:

  • We want to modify an existing data.
  • A form needs to be saved offline and get filled in later.
  • Better user experience, like filling the default dates for hotel or flight bookings.

In this post we’re going to learn how to fill the form with some values the first time it is loaded.

Form requirements

We’re going to build a form that contains the following fields:

  • Name: text field.
  • Flight class: radio button.
  • Terms of service agreement: checkbox.

Define the schema

We’ll skip the custom error messages for the sake of brevity.

schema.ts
import z from "zod";
export const formSchema = z.object({
name: z.string(),
flightClass: z.union([
z.literal("economy"),
z.literal("business"),
z.literal("first-class")
]),
acceptTos: z.boolean(),
});
export type Form = z.TypeOf<typeof formSchema>;

Build the UI

We build the UI the same way we always do.

App.tsx
export default function App() {
const {
register,
formState: { errors },
handleSubmit,
} = useForm<Form>({
resolver: zodResolver(formSchema),
});
return (
<form
onSubmit={handleSubmit((data) => {
console.log(data);
})}
>
<div>
<label>Name</label>
<input {...register('name')} />
</div>
<div className="field">
<label>Flight Class</label>
<div>
<input
type="radio"
value="economy"
{...register('flightClass')}
/>
<label>Economy</label>
</div>
<div>
<input
type="radio"
value="business"
{...register('flightClass')}
/>
<label>Business</label>
</div>
<div>
<input
type="radio"
value="first-class"
{...register('flightClass')}
/>
<label>First Class</label>
</div>
</div>
<div>
<input type="checkbox" {...register('acceptTos')} />
<label>I agree to the terms and services</label>
</div>
<button type="submit">Submit</button>
</form>
);
}
Empty form

Setting default value

In order to set default values to our form, all we need to do is provide the value in the hook.

App.tsx
export default function App() {
const {
register,
formState: { errors },
handleSubmit,
} = useForm<Form>({
resolver: zodResolver(formSchema),
defaultValues: {
name: 'Tom Lee',
flightClass: 'business',
acceptTos: true,
}
});
return (
// ...
)
}

Now the prefilled data should show up the first time you open the page.

Form prefilled with data

Wrapping Up

Here’s the sandbox code for you to try it yourself.