Handling Input Fields in React JS
Handling Input Fields in React JS means collecting, storing, updating, validating, and processing the information entered by users through text boxes, email fields, password fields, checkboxes, radio buttons, dropdowns, and other form elements. React commonly uses the useState() Hook and event handlers such as onChange to manage input values and update the user interface.
Learn more: JustAcademy React JS Training Course | Register for React JS Course Demo
1. Learning Objectives
- Understand how input fields work in React.
- Manage input values using the
useState() Hook.
- Handle user input using
onChange events.
- Work with text, email, password, number, checkbox, radio, and select fields.
- Manage multiple input fields using a single state object.
- Validate input data and display error messages.
- Handle form submission and reset form values.
2. What Are Input Fields?
Input fields are HTML form elements that allow users to enter or select information. In React, these elements are written using JSX and can be connected to component state.
Common Input Field Types
| Input Type |
Purpose |
Example |
| Text |
Collects general text |
Full name |
| Email |
Collects an email address |
[email protected] |
| Password |
Collects hidden password text |
Account password |
| Number |
Collects numeric input |
Age or quantity |
| Checkbox |
Allows a user to select or deselect an option |
Accept terms |
| Radio |
Allows one choice from a related group |
Education level |
| Select |
Allows selection from a dropdown |
Choose a city |
| Textarea |
Collects multiple lines of text |
Address or feedback |
| Date |
Collects a date |
Date of birth |
| File |
Allows users to choose a file |
Upload a resume |
3. Understanding State in Input Fields
State is data stored by a React component. When state changes, React can re-render the component to display the updated information. The useState() Hook is commonly used to store the current value of an input field.
Basic Syntax
const [value, setValue] = useState('');
value: stores the current input value.
setValue: updates the state.
useState(''): initializes the value as an empty string.
Example: Managing a Text Input
import { useState } from 'react';
function NameInput() {
const [name, setName] = useState('');
return (
<div>
<label htmlFor="name">Enter your name:</label>
<input
id="name"
type="text"
value={name}
onChange={(event) => setName(event.target.value)}
placeholder="Enter your name"
/>
<p>Your name is: {name}</p>
</div>
);
}
export default NameInput;
Explanation: The name state stores the entered text. The onChange handler reads the latest value from event.target.value and updates the state. React then displays the updated value in the paragraph.
4. Controlled Input Fields
A controlled input is a form element whose displayed value is managed by React state. For text inputs, the value prop determines the displayed value, while onChange updates the state when the user types.
Example
import { useState } from 'react';
function ControlledInput() {
const [email, setEmail] = useState('');
return (
<input
type="email"
value={email}
onChange={(event) => setEmail(event.target.value)}
placeholder="Enter email"
/>
);
}
export default ControlledInput;
Important: A controlled text input should have a corresponding onChange handler that updates its state. Otherwise, it may behave like a read-only field. Initialize text values with a string, such as '', rather than undefined or null.
5. Handling Different Input Types
5.1 Text Input
const [username, setUsername] = useState('');
<input
type="text"
value={username}
onChange={(event) => setUsername(event.target.value)}
/>
Text inputs are useful for names, usernames, titles, and other short text values.
5.2 Email Input
const [email, setEmail] = useState('');
<input
type="email"
value={email}
onChange={(event) => setEmail(event.target.value)}
placeholder="[email protected]"
/>
The email input provides browser-level input assistance, but applications should still validate data appropriately before processing it.
5.3 Password Input
const [password, setPassword] = useState('');
<input
type="password"
value={password}
onChange={(event) => setPassword(event.target.value)}
placeholder="Enter password"
/>
The password input masks the characters on screen. Masking does not encrypt or securely store the password; sensitive information must be handled securely by the application.
5.4 Number Input
const [age, setAge] = useState('');
<input
type="number"
min="1"
max="120"
value={age}
onChange={(event) => setAge(event.target.value)}
/>
Input values from event.target.value are generally strings, including values from number inputs. Convert them to numbers when performing numeric calculations, and handle empty values before conversion.
5.5 Textarea
const [message, setMessage] = useState('');
<textarea
value={message}
onChange={(event) => setMessage(event.target.value)}
placeholder="Write your message"
/>
In React, a textarea's content is commonly controlled through its value prop instead of placing initial text between the opening and closing tags.
5.6 Checkbox
const [accepted, setAccepted] = useState(false);
<label>
<input
type="checkbox"
checked={accepted}
onChange={(event) => setAccepted(event.target.checked)}
/>
I accept the terms and conditions
</label>
Use checked to control a checkbox and event.target.checked to read its Boolean state.
5.7 Radio Buttons
const [course, setCourse] = useState('React');
<label>
<input
type="radio"
name="course"
value="React"
checked={course === 'React'}
onChange={(event) => setCourse(event.target.value)}
/>
React JS
</label>
<label>
<input
type="radio"
name="course"
value="Flutter"
checked={course === 'Flutter'}
onChange={(event) => setCourse(event.target.value)}
/>
Flutter
</label>
Radio buttons that belong to the same group should share a name. The state can store the selected option.
5.8 Select Dropdown
const [city, setCity] = useState('');
<select
value={city}
onChange={(event) => setCity(event.target.value)}
>
<option value="">Select a city</option>
<option value="Mumbai">Mumbai</option>
<option value="Pune">Pune</option>
<option value="Delhi">Delhi</option>
</select>
The selected dropdown option is controlled by the select element's value prop.
5.9 File Input
function ResumeUpload() {
const [fileName, setFileName] = useState('');
function handleFileChange(event) {
const file = event.target.files?.[0];
setFileName(file ? file.name : '');
}
return (
<div>
<input
type="file"
accept=".pdf,.doc,.docx"
onChange={handleFileChange}
/>
<p>Selected file: {fileName || 'No file selected'}</p>
</div>
);
}
File inputs are a special case: browsers manage the selected file, so they are not controlled like ordinary text inputs. Read selected files from event.target.files.
6. Handling Multiple Input Fields with One State Object
For forms with several fields, you can store their values in a single state object. Use the spread syntax (...) to preserve the other fields when updating one property.
Example
import { useState } from 'react';
function StudentForm() {
const [formData, setFormData] = useState({
name: '',
email: '',
phone: ''
});
function handleChange(event) {
const { name, value } = event.target;
setFormData((previousData) => ({
...previousData,
[name]: value
}));
}
return (
<form>
<input
name="name"
value={formData.name}
onChange={handleChange}
placeholder="Full name"
/>
<input
name="email"
type="email"
value={formData.email}
onChange={handleChange}
placeholder="Email"
/>
<input
name="phone"
type="tel"
value={formData.phone}
onChange={handleChange}
placeholder="Phone number"
/>
<pre>{JSON.stringify(formData, null, 2)}</pre>
</form>
);
}
export default StudentForm;
How it works:
- Each input has a unique
name matching a property in the state object.
- The shared handler reads the input's
name and value.
- The spread operator keeps existing values.
- The computed property name
[name] updates only the field that changed.
7. Understanding the onChange Event
The onChange event handler runs when the user changes an input. For controlled inputs, it is commonly used to synchronize the input with React state.
function handleChange(event) {
console.log(event.target.value);
}
Useful event properties include:
event.target: the input element that triggered the event.
event.target.value: the current value of a text field, select, or similar input.
event.target.checked: the selected state of a checkbox or radio button.
event.target.name: the field's name.
event.target.files: the selected files in a file input.
8. Handling Form Submission
When a form is submitted, React can read the values stored in state and process them. Use an onSubmit handler and call event.preventDefault() when you want to prevent the browser's default page navigation or reload.
import { useState } from 'react';
function LoginForm() {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
function handleSubmit(event) {
event.preventDefault();
console.log({
email,
password
});
}
return (
<form onSubmit={handleSubmit}>
<label htmlFor="email">Email</label>
<input
id="email"
type="email"
value={email}
onChange={(event) => setEmail(event.target.value)}
required
/>
<label htmlFor="password">Password</label>
<input
id="password"
type="password"
value={password}
onChange={(event) => setPassword(event.target.value)}
required
/>
<button type="submit">Log In</button>
</form>
);
}
export default LoginForm;
Note: This example demonstrates input handling only. A real login system must send credentials securely to an authentication service rather than relying on console output.
9. Input Validation and Error Messages
Validation checks whether entered information meets the application's requirements. For example, a required name should not be empty, and an email field should contain a valid email address.
Example: Basic Name Validation
import { useState } from 'react';
function NameValidation() {
const [name, setName] = useState('');
const [error, setError] = useState('');
function handleChange(event) {
const value = event.target.value;
setName(value);
if (!value.trim()) {
setError('Name is required.');
} else {
setError('');
}
}
function handleSubmit(event) {
event.preventDefault();
if (!name.trim()) {
setError('Please enter your name.');
return;
}
alert('Form submitted successfully!');
}
return (
<form onSubmit={handleSubmit}>
<label htmlFor="name">Name</label>
<input
id="name"
value={name}
onChange={handleChange}
aria-invalid={Boolean(error)}
aria-describedby="name-error"
/>
{error && <p id="name-error" role="alert">{error}</p>}
<button type="submit">Submit</button>
</form>
);
}
export default NameValidation;
Client-side validation improves the user experience, but important rules must also be enforced on the server because client-side checks can be bypassed.
10. Resetting Input Fields
Controlled inputs can be cleared by resetting their state values.
import { useState } from 'react';
function SearchBox() {
const [search, setSearch] = useState('');
function handleReset() {
setSearch('');
}
return (
<div>
<input
value={search}
onChange={(event) => setSearch(event.target.value)}
placeholder="Search..."
/>
<button type="button" onClick={handleReset}>
Clear
</button>
</div>
);
}
Calling setSearch('') clears the input because its displayed value is linked to the state.
11. Controlled vs. Uncontrolled Inputs
| Feature |
Controlled Input |
Uncontrolled Input |
| Value management |
Managed through React state |
Managed primarily by the DOM |
| Text value |
Usually uses value |
Can use defaultValue |
| Checkbox state |
Uses checked |
Can use defaultChecked |
| Change handling |
Usually updates state through onChange |
State updates are not required for every change |
| Validation and conditional UI |
Convenient for real-time updates |
May require reading values from the DOM |
| Typical use |
Dynamic forms and interactive interfaces |
Simple forms or cases using browser-managed values |
Neither approach is universally best. Choose the method that fits the form's requirements, and avoid switching an input between controlled and uncontrolled during its lifetime.
12. Common Mistakes and Solutions
| Mistake |
Problem |
Solution |
Using value without onChange |
The input may become read-only. |
Add an onChange handler or intentionally use readOnly. |
Using value for checkbox state |
The checked state is not controlled correctly. |
Use checked and event.target.checked. |
| Forgetting the spread operator |
Other properties in a form state object may be lost. |
Use ...previousData before updating one property. |
Initializing a controlled input with undefined |
The input may switch between uncontrolled and controlled. |
Initialize text state with ''. |
| Using the wrong field name |
The wrong state property may be updated. |
Match each input's name to its state property. |
Forgetting preventDefault() |
The page may reload during client-side submission. |
Call it when the default submission behavior should be prevented. |
| Updating state asynchronously inside the input handler |
The displayed value may lag or behave unexpectedly. |
Synchronously update controlled input state from the current event value. |
13. Best Practices for Handling Input Fields
- Use descriptive state variable names, such as
email, password, and phone.
- Use
useState() for values that affect the rendered interface.
- Use controlled inputs when the UI needs to respond to changes immediately.
- Use a shared change handler for related fields when it improves maintainability.
- Use the spread operator when updating one property of an object stored in state.
- Connect every input to a visible, descriptive label.
- Use appropriate input types, such as
email, tel, and password.
- Display clear and accessible validation messages.
- Do not store derived values in separate state if they can be calculated from existing state.
- For large forms, consider reusable input components or a form library when complexity justifies it.
- Never assume client-side validation is sufficient for security.
- Keep sensitive credentials out of logs and unnecessary client-side storage.
14. Mini Project: Student Registration Form
Objective: Create a registration form that collects a student's name, email, phone number, course, and terms acceptance. The form validates required fields and displays the submitted information.
Complete Code
import { useState } from 'react';
function StudentRegistration() {
const initialData = {
name: '',
email: '',
phone: '',
course: '',
acceptedTerms: false
};
const [formData, setFormData] = useState(initialData);
const [error, setError] = useState('');
const [submitted, setSubmitted] = useState(false);
function handleChange(event) {
const { name, value, type, checked } = event.target;
setFormData((previousData) => ({
...previousData,
[name]: type === 'checkbox' ? checked : value
}));
setSubmitted(false);
setError('');
}
function handleSubmit(event) {
event.preventDefault();
if (
!formData.name.trim() ||
!formData.email.trim() ||
!formData.course ||
!formData.acceptedTerms
) {
setError('Complete all required fields and accept the terms.');
setSubmitted(false);
return;
}
setError('');
setSubmitted(true);
}
function handleReset() {
setFormData(initialData);
setError('');
setSubmitted(false);
}
return (
<div>
<h2>Student Registration</h2>
<form onSubmit={handleSubmit}>
<label htmlFor="name">Full Name</label>
<input
id="name"
name="name"
value={formData.name}
onChange={handleChange}
required
/>
<label htmlFor="email">Email</label>
<input
id="email"
name="email"
type="email"
value={formData.email}
onChange={handleChange}
required
/>
<label htmlFor="phone">Phone</label>
<input
id="phone"
name="phone"
type="tel"
value={formData.phone}
onChange={handleChange}
/>
<label htmlFor="course">Choose Course</label>
<select
id="course"
name="course"
value={formData.course}
onChange={handleChange}
required
>
<option value="">Select a course</option>
<option value="React JS">React JS</option>
<option value="Flutter">Flutter</option>
<option value="Selenium">Selenium</option>
</select>
<label>
<input
type="checkbox"
name="acceptedTerms"
checked={formData.acceptedTerms}
onChange={handleChange}
/>
I accept the terms and conditions
</label>
{error && <p role="alert">{error}</p>}
<button type="submit">Register</button>
<button type="button" onClick={handleReset}>Reset</button>
</form>
{submitted && (
<section>
<h3>Registration Successful!</h3>
<p>Name: {formData.name}</p>
<p>Email: {formData.email}</p>
<p>Phone: {formData.phone || 'Not provided'}</p>
<p>Course: {formData.course}</p>
</section>
)}
</div>
);
}
export default StudentRegistration;
Project concepts covered: React state, controlled text fields, email and phone inputs, dropdown selection, checkbox handling, shared event handlers, form validation, submission, and resetting.
Note: This example demonstrates front-end form handling. A production registration form should submit the data to a backend service and validate it there as well.
15. Interview Questions and Answers
Q1. What is input handling in React?
Input handling is the process of reading and updating values entered or selected by users through form elements.
Q2. What is a controlled component?
A controlled input is an element whose displayed value or checked state is driven by React state through props such as value or checked.
Q3. What is the purpose of useState()?
The useState() Hook stores component state and provides a setter function to update it.
Q4. What does onChange do?
The onChange handler responds to user changes and commonly updates the state associated with a controlled input.
Q5. What is the difference between value and defaultValue?
value controls the current value of a controlled input. defaultValue specifies an initial value for an uncontrolled input.
Q6. How do you handle checkbox input?
Use checked to connect the checkbox to state and event.target.checked to read whether it is selected.
Q7. How can multiple fields be managed with one handler?
Give each field a name and use event.target.name with event.target.value to update the matching property in a state object.
Q8. Why is the spread operator used when updating form data?
The spread operator copies existing object properties so that updating one field does not remove the other fields.
Q9. Why is preventDefault() used in form submission?
It prevents the browser's default submission behavior when the application needs to handle the form without a normal page navigation or reload.
Q10. Can file inputs be controlled like text inputs?
File inputs are a special case. Read the selected files from event.target.files; browsers manage the file selection rather than a normal text-like controlled value.
16. Practice Exercises
- Create a text input that displays the user's name below the field.
- Create an email field and show an error when the field is empty.
- Create a password field with a button that toggles password visibility.
- Create a dropdown for selecting a city and display the selected city.
- Create radio buttons for selecting a preferred learning mode.
- Create a checkbox that enables a Submit button only when selected.
- Build a form with name, email, phone, and course fields using a single state object.
- Add a Reset button that clears all fields and validation messages.
- Display a submission confirmation after valid input is provided.
- Upload a resume and display the selected filename.
17. Revision Checklist
- Understand the purpose of React input fields.
- Know how to use
useState().
- Understand controlled and uncontrolled inputs.
- Use
value and onChange for controlled text fields.
- Use
checked and event.target.checked for checkboxes.
- Handle text, email, password, number, select, radio, textarea, and file inputs.
- Manage multiple fields with a state object and spread syntax.
- Handle submission, validation, and resetting.
- Write accessible labels and clear error messages.
- Understand the need for server-side validation.
18. Additional Learning Resources
Conclusion
Handling input fields is an essential part of React JS development. By combining state, event handlers, controlled components, validation, and form submission, developers can create interactive and reliable forms. Practice with different input types and build small projects to strengthen your understanding.
Explore the JustAcademy React JS Training Course and register for a course demo to learn more.