React Forms and User Input
# React Forms and User Input
1. Introduction
Forms are how web applications collect data from users. Whether it's a simple search bar, a login page, or a complex multi-step checkout process, mastering forms is essential. In standard HTML, forms manage their own internal state. In React, we prefer to take control away from HTML and give it to React. We call this pattern Controlled Components.2. Learning Objectives
By the end of this chapter, you will be able to:- Understand what a "Controlled Component" is.
- Bind HTML inputs to React state.
- Handle form submissions effectively.
- Manage multiple inputs in a single form.
3. Beginner-Friendly Explanations
Uncontrolled vs. Controlled Components
-
Uncontrolled (Standard HTML): You type into an
<input>. The browser remembers what you typed. When you hit submit, the browser packages the data and sends it.
-
Controlled (React Pattern): React says, *"I want to be in charge."* You create a state variable
[text, setText] = useState(""). You force the<input>to always display the value oftext. When the user types, theonChangeevent updatestextviasetText(). React is the "single source of truth".
4. Syntax Explanation
Step 1: The Single Input
Let's create a basic controlled input.```jsx id="ch11_ex1" // Example React component import { useState } from 'react';
function SingleInput() { const [name, setName] = useState("");
return ( <div> {/* 1. Value is tied to state. 2. onChange updates state. */} <input type="text" value={name} onChange={(e) => setName(e.target.value)} placeholder="Enter your name" /> <p>Hello, {name}!</p> </div> ); }
jsx id="ch11_ex2" // Example React component function LoginForm() { const [email, setEmail] = useState("");
const handleSubmit = (e) => {
e.preventDefault(); // Stop page reload
alert(Submitting login for ${email});
// Here you would normally send the data to an API
};
return ( <form onSubmit={handleSubmit}> <input type="email" value={email} onChange={(e) => setEmail(e.target.value)} /> <button type="submit">Log In</button> </form> ); }
jsx id="ch11_ex3" // Example React component import { useState } from 'react';
function ComplexForm() { const [formData, setFormData] = useState({ firstName: "", lastName: "" });
const handleChange = (e) => { // We use the 'name' attribute of the input to update the correct field setFormData({ ...formData, // Keep existing data [e.target.name]: e.target.value // Update the specific field }); };
return ( <form> <input name="firstName" value={formData.firstName} onChange={handleChange} /> <input name="lastName" value={formData.lastName} onChange={handleChange} /> </form> ); }
jsx id="ch11_proj1" // Example React component import React, { useState } from 'react';
export default function SignupForm() { const [email, setEmail] = useState(""); const [password, setPassword] = useState(""); const [submitted, setSubmitted] = useState(false);
const onSubmit = (e) => { e.preventDefault(); setSubmitted(true); };
if (submitted) { return ( <div className="max-w-md mx-auto mt-10 p-6 bg-green-50 text-green-700 rounded-lg text-center font-bold"> Welcome aboard! Your account for {email} has been created. </div> ); }
return ( <div className="max-w-md mx-auto mt-10 p-8 bg-white rounded-xl shadow-lg border border-gray-100"> <h2 className="text-2xl font-bold mb-6 text-gray-800 text-center">Create Account</h2> <form onSubmit={onSubmit} className="space-y-4"> <div> <label className="block text-sm font-medium text-gray-700 mb-1">Email</label> <input type="email" required value={email} onChange={(e) => setEmail(e.target.value)} className="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 outline-none" placeholder="you@example.com" /> </div> <div> <label className="block text-sm font-medium text-gray-700 mb-1">Password</label> <input type="password" required value={password} onChange={(e) => setPassword(e.target.value)} className="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 outline-none" placeholder="••••••••" /> {/* Live validation feedback */} {password.length > 0 && password.length < 6 && ( <p className="text-red-500 text-xs mt-1">Password must be at least 6 characters</p> )} </div>
<button
type="submit"
disabled={password.length < 6}
className="w-full bg-blue-600 text-white font-bold py-2 px-4 rounded-lg hover:bg-blue-700 disabled:bg-gray-400 transition"
>
Sign Up
</button>
</form>
</div>
);
}
``
12. Coding Challenges
Challenge 1: Add a "Confirm Password" field to the Signup form. The submit button should be disabled unless password perfectly matches confirmPassword.
13. MCQs with Answers
Q1: In a Controlled Component, what is the single source of truth for the input's data?
A) The HTML DOM
B) The React State
C) The server
D) LocalStorage
*Answer: B*
Q2: What happens if you set
value={myState} on an input but do NOT provide an onChange handler?
A) The input works normally.
B) React crashes immediately.
C) The input becomes read-only and ignores user typing.
D) The input clears itself on every keypress.
*Answer: C*
14. Interview Questions
-
Q: Explain the difference between Controlled and Uncontrolled components in React.
-
Q: How do you handle forms with many inputs without writing dozens of
useState hooks?
15. FAQs
Can I use a checkbox as a controlled component?
Yes! But instead of value, you use checked={myBooleanState}, and in the onChange handler, you read e.target.checked instead of e.target.value.
16. Summary
Forms are critical for user interaction. By tying the value of your inputs to React state variables and updating that state via onChange handlers, you create Controlled Components. This pattern gives React total control over the UI, enabling powerful features like live validation and dynamic UI updates.
17. Next Chapter Recommendation
You've been using useState` for a while now, but it's time to dive deeper. In Chapter 12: React useState Hook, we will take a closer look at advanced state techniques, updating state based on previous state, and the rules of React Hooks.