Day 6: Forms & Validation
Day 6: Forms & Validation
Dealing with user input is a core part of most apps. In React, we typically use Controlled Components.
Recap: Controlled Components
As we saw in Day 3, a controlled component is an input where the React state acts as the “single source of truth”.
const [email, setEmail] = useState('');
<input value={email} onChange={(e) => setEmail(e.target.value)} />
Handling Multiple Inputs
Imagine a signup form with First Name, Last Name, Email, and Password. Creating 4 separate useState hooks is fine, but it can get messy.
We can use a single object for state.
function SignupForm() {
const [formData, setFormData] = useState({
firstName: '',
lastName: '',
email: '',
});
function handleChange(e) {
// Dynamic key access: [e.target.name]
setFormData({
...formData,
[e.target.name]: e.target.value,
});
}
return (
<form>
<input
name="firstName"
value={formData.firstName}
onChange={handleChange}
placeholder="First Name"
/>
<input
name="lastName"
value={formData.lastName}
onChange={handleChange}
placeholder="Last Name"
/>
<input
name="email"
value={formData.email}
onChange={handleChange}
placeholder="Email"
/>
</form>
);
}
Form Submission
The default behavior of an HTML form submit is to reload the page. In React, we want to prevent that.
function handleSubmit(e) {
e.preventDefault(); // Stop page reload
console.log('Form Submitted:', formData);
// Send formData to an API...
}
return <form onSubmit={handleSubmit}>...</form>
Validation
Validation is just logic checking your state.
function LoginForm() {
const [email, setEmail] = useState('');
const [error, setError] = useState('');
function handleSubmit(e) {
e.preventDefault();
if (!email.includes('@')) {
setError('Invalid email address');
return;
}
setError('');
console.log('Login successful');
}
return (
<form onSubmit={handleSubmit}>
<input value={email} onChange={(e) => setEmail(e.target.value)} />
{error && <p style={{ color: 'red' }}>{error}</p>}
<button type="submit">Login</button>
</form>
);
}
React Hook Form
For complex forms, manual state handling gets tedious. The community standard library is React Hook Form.
npm install react-hook-form
import { useForm } from "react-hook-form";
function App() {
const { register, handleSubmit, formState: { errors } } = useForm();
const onSubmit = data => console.log(data);
return (
<form onSubmit={handleSubmit(onSubmit)}>
{/* "register" links the input to the hook */}
<input {...register("firstName", { required: true })} />
{errors.firstName && <span>This field is required</span>}
<input type="submit" />
</form>
);
}
This library reduces re-renders and code amount significantly.
Homework for Day 6:
- Build a basic “Contact Us” form (Name, Email, Message).
- Validate that Name is not empty and Message is at least 10 characters long.
- Show error messages below the inputs.
- On valid submit, clear the form and show a “Success!” message.
Day 7 brings us to Global State with Context!