Forms: Controlled & Uncontrolled Components
5 questions foundWhat is a controlled form input in React?
Beginner A controlled input gets its current value from React state and updates that state every time the user types, using the onChange event. This means React always knows exactly what the input currently shows, making it easy to validate or transform the value at any moment.
function NameInput() {
const [name, setName] = useState('');
return (
<input
value={name}
onChange={(e) => setName(e.target.value)}
/>
);
}
Real-world example A signup form keeps track of a user's chosen username in state as they type, letting the app instantly check and show whether that username is already taken, without waiting for the user to submit the form first.
Common follow-ups: What happens if you provide a value prop to an input without also giving it an onChange handler?;How do you clear a controlled input's value programmatically?
Components & JSX;State Management
What is an uncontrolled form input, and how does it differ from a controlled one?
Beginner An uncontrolled input keeps its own value internally in the actual HTML element, similar to how forms worked before React existed. Instead of tracking every keystroke in state, you read the input's current value only when you need it, usually using a ref, such as when the form is submitted.
function NameInput() {
const inputRef = useRef(null);
function handleSubmit() {
alert(`Name entered: ${inputRef.current.value}`);
}
return (
<>
<input ref={inputRef} defaultValue="" />
<button onClick={handleSubmit}>Submit</button>
</>
);
}
Real-world example A simple contact form reads the message field's value only when the user clicks submit, using an uncontrolled input with a ref, since there is no need to react to every single keystroke as it happens.
Common follow-ups: When would you choose an uncontrolled input over a controlled one?;What does the defaultValue prop do differently from the value prop?
Refs useRef & forwardRef;Components & JSX
How would you validate a form in React and show an error message to the user?
Intermediate You keep track of any validation errors in state alongside your form values, and check the input against your rules either as the user types or when they try to submit. If a rule fails, you update the error state and display a message near the relevant field.
function SignupForm() {
const [email, setEmail] = useState('');
const [error, setError] = useState('');
function handleSubmit(e) {
e.preventDefault();
if (!email.includes('@')) {
setError('Please enter a valid email address');
return;
}
setError('');
submitForm(email);
}
return (
<form onSubmit={handleSubmit}>
<input value={email} onChange={(e) => setEmail(e.target.value)} />
{error && <p style={{ color: 'red' }}>{error}</p>}
<button type="submit">Sign Up</button>
</form>
);
}
Real-world example A signup form shows a clear red error message right below the email field the moment a user tries to submit an invalid email address, instead of silently doing nothing or crashing.
Common follow-ups: How would you validate multiple fields at once and track separate errors for each?;What is the benefit of using a form library like React Hook Form instead of writing this by hand?
Error Handling;Design Patterns in React
How does React Hook Form simplify building forms compared to managing every field with useState manually?
Advanced React Hook Form lets you register each input once and handles tracking its value, validation, and errors internally, without causing your component to re render on every single keystroke like a manually controlled input often does. This makes forms both easier to write and noticeably faster, especially for forms with many fields.
import { useForm } from 'react-hook-form';
function SignupForm() {
const { register, handleSubmit, formState: { errors } } = useForm();
function onSubmit(data) {
console.log(data);
}
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register('email', { required: true })} />
{errors.email && <p>Email is required</p>}
<button type="submit">Sign Up</button>
</form>
);
}
Real-world example A job application form with twenty different fields uses React Hook Form to avoid slowing down as the user types, since it does not re render the entire form on every keystroke the way a fully manually controlled form would.
Common follow-ups: Why does React Hook Form avoid unnecessary re renders compared to a fully controlled approach?;How would you add custom validation rules beyond simply marking a field as required?
Performance (memo/useMemo);Custom Hooks
How do you prevent a form from reloading the page when it is submitted in React?
Intermediate By default, submitting an HTML form reloads the entire page. In React, you call preventDefault on the submit event inside your onSubmit handler, which stops the browser's default reload behavior and lets your JavaScript code handle the submission instead.
function ContactForm() {
function handleSubmit(event) {
event.preventDefault();
console.log('Form submitted without reloading the page');
}
return (
<form onSubmit={handleSubmit}>
<button type="submit">Send</button>
</form>
);
}
Real-world example A contact form smoothly shows a thank you message after submission, without the jarring full page reload that would normally happen if preventDefault had not been called on the submit event.
Common follow-ups: What happens if you forget to call preventDefault inside your submit handler?;Is there a difference in behavior between an onClick handler on the button versus an onSubmit handler on the form?
Components & JSX;Error Handling