Language
- EN
- ID
Master Table of Contents
- See full index in [01. Introduction]
Who this chapter is for
- Learners building real user flows like signup, login, checkout, and profile edit
- Beginners who are tired of messy form logic and random validation bugs
- Anyone who wants forms that feel smooth, clear, and trustworthy
What you’ll learn
- Controlled input patterns that scale beyond one or two fields
- Practical validation strategy with useful UX feedback
- Submit lifecycle handling: idle, validating, loading, success, and error
Why this topic matters
Forms are where product quality becomes obvious. If your form feels broken, users leave fast.
Good form architecture gives you cleaner code, fewer backend validation issues, and way better user trust. This is one of the highest-impact React skills you can build early.
Core concepts
Controlled components
- Input value tied to React state
- Single source of truth
When inputs are controlled, your UI and data never go out of sync.
Validation
- Field-level checks (required, format, min length)
- Form-level checks before submit
Validation goal is not to “block users.” It is to guide users quickly to a valid result.
Submit states
- Loading, success, and error feedback
- Disable submit when invalid or submitting
Treat submit as a lifecycle, not a single click event.
Step-by-step walkthrough
Step 1 — Build form state model
Create one state model for:
- field values,
- field errors,
- submit status.
Step 2 — Add reusable validation functions
Write small validation helpers that return consistent messages.
Keep messages human: clear, direct, and actionable.
Step 3 — Handle submit lifecycle
Flow recommendation:
- Clear old errors
- Run validation
- Stop early if invalid
- Submit request
- Handle success/error state clearly
Practical examples
Example 1 — Controlled input
const [email, setEmail] = useState("");
<input value={email} onChange={(e) => setEmail(e.target.value)} />;
Tip:
- Controlled inputs make validation and conditional UI way easier.
Example 2 — Basic validation
function validateEmail(value: string): string | null {
if (!value.includes("@")) return "Email is invalid";
return null;
}
Next step:
- Expand this pattern into
validateForm(values)that returns an error object.
Common mistakes and how to avoid them
- Validating only on submit -> add live feedback for important fields
- Returning inconsistent error formats -> standardize validation output shape
- Not disabling submit while loading -> users can trigger duplicate requests
- Showing technical backend errors directly -> map them into user-friendly messages
Mini Project
- Build a signup form with:
- real-time validation for email and password,
- submit loading state,
- clear success and error alerts,
- disabled submit while request is running.
Bonus:
- Add confirm-password validation and password strength hints.
Quick practice
- Add required and email-format checks
- Show field-level error messages
- Prevent submit if any validation fails
- Add one top-level form error area for server-side errors
Key takeaways
- Controlled inputs keep data flow predictable
- Validation should help users recover quickly, not just reject input
- Clear submit-state handling prevents duplicate requests and confusion
Next step
Continue to [12. Routing and App Structure].
No Comments