Forms in React: Mastering Controlled Components
Learn the fundamental React pattern for creating interactive and predictable forms that are easy to manage and validate.
/* Let's build a form... */
State: The Single Source of Truth
The foundation of forms in React is state. For each input field, you'll have a piece of state that holds its current value. This makes your React component the "single source of truth" for the form's data. We typically start by initializing the state with <useState>
.
Handling User Input with `onChange`
To update the state as the user types, you need an event handler. This function is attached to the input's <onChange>
event. Inside the handler, you'll call your state setter function (e.g., setUsername ) with the new value from <event.target.value>
.
Controlled Components: Connecting State and UI
A controlled component is an input element whose value is controlled by React. You achieve this by binding the input's <value>
prop to your state variable and its <onChange>
` prop to your event handler. This creates a two-way data flow: state updates the input, and user actions update the state.
Submitting the Form with `onSubmit`
Finally, to handle the form submission, you attach an <onSubmit>
event handler to the <form>
element. Inside this function, you must call `event.preventDefault()` to stop the browser's default behavior of reloading the page. Here, you can access the final form data from your state for validation or API calls.
Practice Zone
Interactive Test 1: Match the Concept
Match the form attribute to its correct role in a controlled component.
Arrastra en el orden correspondiente.
Arrastra las opciones:
Completa el código:
Interactive Test 2: Complete the Code
Rellena los huecos en cada casilla.
function Login() { const [username, ] = useState(''); const handleChange = (e) => { setUsername(e.); } return <input value={username} onChange={handleChange} />; }
Practice Example: Code Editor
Create a component with an email input and a password input. Both should be controlled components.
Forms in Action
Handling forms is more than just text inputs. Let's explore how controlled components adapt to other common form elements and validation strategies.
1. Handling Multiple Inputs
Instead of a separate useState
for each input, you can use a single state object. To update it, use the input's name
attribute to dynamically choose which property to update. This keeps your code clean and scalable.
const [formData, setFormData] = useState({ email: '', password: '' });
const handleChange = (e) => {
const { name, value } = e.target;
setFormData(prevData => ({
...prevData,
[name]: value
}));
}
2. Other Input Types (textarea
, select
)
The controlled component pattern works beautifully for other elements too. A textarea
uses value
and onChange
just like a text input. For a select
dropdown, you set the value
on the <select>
tag itself to control the selected option.
<textarea value={bio} onChange={(e) => setBio(e.target.value)} />
<select value={userRole} onChange={(e) => setUserRole(e.target.value)}>
<option value="user">User</option>
<option value="admin">Admin</option>
</select>
3. Basic Form Validation
Since you have the form data in your state, you can validate it at any time. A common approach is to check the data inside the `onSubmit` handler before proceeding. You can then set an error message in state to provide feedback to the user.
const handleSubmit = (e) => {
e.preventDefault();
if (password.length < 8) {
setError('Password must be at least 8 characters long.');
} else {
setError('');
// Submit data...
}
}
Practical Takeaway: The controlled components pattern provides a predictable and powerful way to manage all user input, giving you full control over form data and enabling easy implementation of features like validation and dynamic fields.
React Forms Glossary
- Controlled Component
- A form input element whose value is controlled by React state. The state is the "single source of truth," and it's updated via an `onChange` handler.
- Uncontrolled Component
- A form input where the state is handled by the DOM itself. In React, you would typically use a `ref` to get its value when needed, but this is less common.
- `event.target`
- A property of the event object that refers to the DOM element that triggered the event. For forms, `event.target.value` gives you the current value of the input.
- `event.preventDefault()`
- A method called within an event handler (typically `onSubmit`) to stop the browser's default action. For forms, this prevents a full-page reload on submission.
- Single Source of Truth
- A core principle in React where the state of your component is the definitive source of data for the UI. Any changes to the data must happen by updating the state.