Reusable Forms and Validation
Reusable Forms and Validation
Welcome to your first lesson in the course Forms, Validation & Creating Tasks.
In this lesson, you’ll move from displaying data to collecting it through forms. Forms are the bridge between users and your app — they let users create, edit, or share information.
But forms can get messy if you repeat code for every field or skip validation. That’s why we’ll learn two important patterns:
- Building a reusable input component, so all your text fields look and behave consistently.
- Using validation, so users can’t submit incomplete or incorrect information.
By the end of this lesson, you’ll have a clean, reusable Input component and a TaskForm that validates data before submitting it.
Quick Recap: Where We Are
So far in your project, you’ve built a functional frontend structure.
You already have:
- A dashboard layout with a header and sidebar navigation (in
src/app/(dashboard)/layout.tsx). - A dashboard page that shows task statistics (total, completed, incomplete).
- A tasks list page that displays existing tasks in a clean, read-only list.
- Reusable UI pieces like the Button and TaskRow components.
Up until now, the user experience has been read-only — users can see their tasks but not create new ones.
In this lesson, we’ll change that by building a reusable form for creating tasks.
Building a Reusable Input Component
Understanding the Input Component Step by Step
Building the TaskForm Component
Now that you have a reusable input, let’s build the form that will use it.
Here’s the code:
This defines the validation schema with Zod:
titleandcontentare required fields.dueDateis optional.
By using zodResolver, React Hook Form will automatically check these rules every time the user submits.
Setting Up React Hook Form
Here’s what each part does:
useForm()initializes form state.register()connects input fields to the form’s tracking system.handleSubmit()handles validation and calls your submit function only if validation passes.errorsstores any validation messages generated by Zod.isSubmittingtells us if the form is currently being submitted — useful for disabling buttons.defaultValuessets initial field values, so the form can be reused for both creating and editing tasks. In this unit, you only use the form for creating tasks;initialValuesis included now to prepare for a later edit flow.
Using the Input Component and Validation Together
Here’s what’s happening:
register('title')links this field to React Hook Form and the Zod schema.- If the user leaves it empty, Zod will generate an error (“Title is required”).
- That message is stored in
errors.title.messageand displayed below the field.
The same logic applies for content and dueDate.
The form also includes a <textarea> for task content and uses the Input component again for the due date (this time with type="date").
Handling Submission
handleSubmitruns validation automatically.- If validation passes, it calls your
onSubmitfunction with the form data. - While submitting,
isSubmittingdisables the button to prevent multiple submissions. submitLabellets you customize the button text (e.g., “Save”, “Create”).
Why Use Zod and React Hook Form Together
- Zod defines your rules.
- React Hook Form enforces them, handles state, and manages inputs efficiently.
Zod ensures your form’s data is always valid.
React Hook Form ensures your UI stays performant — it doesn’t re-render the entire form on every keystroke.
The combination keeps your code type-safe, compact, and easy to maintain.
The “New Task” Page
Now that the TaskForm is ready, it’s used in a new page under src/app/(dashboard)/tasks/new/page.tsx:
For now, when you submit, it simply shows an alert.
In future lessons, this will connect to your backend API to actually create a new task.
Summary
In this lesson, you learned how to:
- Create a reusable Input component that handles labels, styling, and validation states.
- Build a TaskForm that collects task information and validates it using React Hook Form and Zod.
- Understand how
register,errors, andhandleSubmitwork together to manage form logic. - Set up the structure for your New Task page, ready for backend integration in upcoming units.
By combining reusability with strong validation, you’re laying the foundation for robust, user-friendly forms throughout your Next.js app.
