React JS Forms
Learn how React manages form controls using state, refs, event handlers and validation. The examples progress from one input to a complete placement registration form.
1. Forms and State
HTML form controls maintain their own internal value when a user types, checks, or selects something. React applications often need these values for validation, filtering, previews, or sending data to an API.
Controlled form
React state supplies the value, and an event handler updates the state. This gives the component a single source of truth.
Uncontrolled form
The DOM keeps the current value. React can read it through a ref when the form is submitted.
2. Controlled Input
In a controlled input, every change is stored in React state and the UI can show a live preview.
import { useState } from 'react';
export default function App() {
const [name, setName] = useState('');
return (
<main>
<label htmlFor="student-name">Student name</label>
<input
id="student-name"
value={name}
onChange={e => setName(e.target.value)}
/>
<p>Hello, {name || 'student'}!</p>
</main>
);
}value and onChange. Using value alone makes it effectively read-only.3. Uncontrolled Input
The DOM stores the input value until submission. React uses useRef to read that current DOM value.
import { useRef, useState } from 'react';
export default function App() {
const commentRef = useRef(null);
const [submitted, setSubmitted] = useState('');
function handleSubmit(event) {
event.preventDefault();
setSubmitted(commentRef.current.value);
}
return (
<>
<form onSubmit={handleSubmit}>
<label htmlFor="comment">Comment</label>
<input id="comment" ref={commentRef} defaultValue="Nice lab" />
<button type="submit">Submit</button>
</form>
<p>Submitted: {submitted}</p>
</>
);
}value without onChange if you intend the control to remain uncontrolled.4. Form Submission and preventDefault()
A browser normally submits a form by navigating or reloading the page. In a single-page React application, use onSubmit and call event.preventDefault() before processing the data.
function handleSubmit(event) {
event.preventDefault();
// validate and process form data
}
<form onSubmit={handleSubmit}>...</form>onSubmit, not only on a button's click, so keyboard users can submit using Enter.5. Basic Validation
Use native attributes such as required plus custom validation feedback before accepting a form.
const [code, setCode] = useState('');
const [message, setMessage] = useState('');
function handleSubmit(event) {
event.preventDefault();
if (code.length !== 6) {
setMessage('Code must contain exactly 6 characters');
return;
}
setMessage('Verification successful');
}6. Handling Multiple Inputs
Real forms commonly have several inputs. A convenient pattern is one state object with a property for each field, updated using the input's name.
function handleChange(event) {
const { name, value, type, checked } = event.target;
setForm(previous => ({
...previous,
[name]: type === 'checkbox' ? checked : value
}));
}previous = old form data → ...previous = keep old fields → [name]: value = change the field the user edited.Why [name]?
name = "fname"; value = "Avinash"; [name]: value // becomes: fname: "Avinash"
In one sentence: keep the old form data, but update the field whose name matches the input that changed.
7. Text, Checkbox, Textarea, Select, Radio and File
The practical example in the source combines several important form controls in one state object.
Interactive Student Form
function handleChange(event) {
const { name, value, checked, type, files } = event.target;
const file = files?.[0];
setForm(previous => ({
...previous,
[name]:
type === 'checkbox'
? checked
? [...previous.skills, value]
: previous.skills.filter(skill => skill !== value)
: type === 'number'
? Number(value)
: type === 'file'
? file ? `${file.name} (${file.size} bytes)` : previous.resume
: value
}));
}8. Complete Practical Form
The uploaded notes finish with a placement registration form using state for name, email, branch, skills, address, state, relocation, mobile and resume, then show a registration message and a readable preview.
const [form, setForm] = useState({
name: '',
email: '',
branch: '',
skills: [],
address: '',
state: 'Select State',
relocation: '',
mobile: 0,
resume: 'No file uploaded'
});
const [submittedData, setSubmittedData] = useState(null);
const [message, setMessage] = useState("");
function handleSubmit(event) {
event.preventDefault();
setSubmittedData(form);
setMessage("Registration Success...!");
}9. Registration Preview
After submission, the source displays the submitted data as normal readable text. The document also contains a JSON preview variant.
{submittedData && (
<div className="preview">
<h2>Registration Preview</h2>
<p><strong>Name:</strong> {submittedData.name}</p>
<p><strong>Email:</strong> {submittedData.email}</p>
<p><strong>Branch:</strong> {submittedData.branch}</p>
<p><strong>Skills:</strong> {submittedData.skills.join(', ')}</p>
...
</div>
)}10. Common Pitfalls & Source Notes
Controlled input
value needs onChange; otherwise the input is effectively read-only.
Checkboxes
Use checked to reflect the selected state and event.target.checked to update it.
Object state
Use the spread operator to preserve other fields when changing one property.
Form submit
Use onSubmit and preventDefault() rather than putting all logic only on button click.
File input
The source stores a readable file name/size string rather than the file object itself in the example.
Source example check
The earlier “Student profile form using input tags” uses initial fields named fname/fbranch/fyear but later reads form.name/form.branch/form.year. Check those property names before running that exact snippet.
Quick Reference
value={name}Controlled value comes from state.onChange={...}Updates controlled state.defaultValue="Nice lab"Initial value for an uncontrolled input.useRef(null)Get access to a DOM value/element.event.preventDefault()Stop normal browser submission.[name]: valueUpdate the property named by the input.checkedCheckbox state.files?.[0]First selected file.11. Quick Check
event.preventDefault() used on submit?
[name]: value allow?