Based on the uploaded 13-page React Forms notes

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.

Controlled inputsUncontrolled inputs useStateuseRefValidation Checkbox arraysLive preview

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.

User changes control
→
Event handler
→
React state / DOM
→
UI / form processing
One-way data flow: In a controlled input, state supplies the value and the event handler updates that state.

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>
  );
}
Hello, student!
Common pitfall: A controlled input needs both 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>
    </>
  );
}
Submitted:
Important: Do not add 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>
Accessibility tip from the source: Put the main logic on the form's onSubmit, not only on a button's click, so keyboard users can submit using Enter.
Try submitting. The page will not reload.

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');
}
Enter exactly six characters.
Waiting for verification.

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
  }));
}
Think in 3 steps: previous = old form data → ...previous = keep old fields → [name]: value = change the field the user edited.

Why [name]?

[name]: value → fname: "Avinash"
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

Skills:
Ready to Relocate:
Fill the form and register to see the preview.
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...!");
}
The source’s page-9 image also shows the intended “Complete Practical Form” layout with Name, Email, Branch, Skills, Address, State, Relocation, Mobile, Resume upload and Register button.
Source document screenshot of the complete practical registration form
Visual reference from the uploaded document (page 9): Complete Practical Form / Placement Registration.

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>
)}
No registration submitted yet.

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.

Source wording: the uploaded notes intentionally distinguish controlled and uncontrolled inputs. Do not treat them as interchangeable patterns.

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

1. In a controlled input, where is the current value stored?
2. Which Hook is used in the uncontrolled example to read the input?
3. Why is event.preventDefault() used on submit?
4. For a checkbox, which property is used to know whether it is selected?
5. What does [name]: value allow?