React handles checkbox and radio inputs as controlled components, just like text fields. Instead of using the value property to reflect the current selection, these inputs mainly rely on the checked attribute plus onChange handlers that update React state.
By binding the UI to state, your checkboxes and radio buttons always stay in sync with the underlying data, making complex forms predictable and easier to debug.
checked attribute instead of value.name attribute and allow only one selection per group.onChange and update React state accordingly.A checkbox in React is controlled by mapping a boolean state to the checked prop and updating that state inside an onChange handler:
Radio buttons work similarly but represent a single choice from a fixed set. All radio buttons in a group share the same name and compare state against their individual value.
For multiple checkboxes (multi-select), we typically use an array in state and push / filter values in response to user actions.
A single checkbox can be controlled using a boolean state variable that tracks whether the option is enabled or disabled.
// Single checkbox with controlled React state
import React, { useState } from "react";
function SingleCheckbox() {
const [isSubscribed, setIsSubscribed] = useState(false);
const handleChange = (e) => setIsSubscribed(e.target.checked);
return (
<div>
<h4>Single Checkbox Example</h4>
<label>
<input
type="checkbox"
checked={isSubscribed}
onChange={handleChange}
/>
Subscribe to Newsletter
</label>
<p className="mt-2">
Status: {isSubscribed ? "Subscribed ✅" : "Not Subscribed ❌"}
</p>
</div>
);
}
export default SingleCheckbox;
When you tick the checkbox, the isSubscribed state becomes true, and the text updates to “Subscribed ✅”. When you untick it, the state becomes false and the message changes to “Not Subscribed ❌”. The UI always mirrors the current boolean value.
When you have several checkboxes (for example, selecting hobbies), it’s convenient to store the selected values inside an array and add or remove entries as the user clicks.
// Manage multiple checkbox selections using an array
import React from "react";
function MultiCheckbox() {
const [hobbies, setHobbies] = React.useState([]);
const handleChange = (e) => {
const { value, checked } = e.target;
if (checked) {
setHobbies([...hobbies, value]);
} else {
setHobbies(hobbies.filter((hobby) => hobby !== value));
}
};
return (
<div>
<h4>Select Your Hobbies</h4>
<label className="me-3">
<input type="checkbox" value="Reading" onChange={handleChange} /> Reading
</label>
<label className="me-3">
<input type="checkbox" value="Music" onChange={handleChange} /> Music
</label>
<label className="me-3">
<input type="checkbox" value="Traveling" onChange={handleChange} /> Traveling
</label>
<p className="mt-3">
Selected: {hobbies.length > 0 ? hobbies.join(", ") : "None"}
</p>
</div>
);
}
export default MultiCheckbox;
Each time you tick a hobby, its label (e.g., "Music") is added to the hobbies array. Unticking removes it. The paragraph at the bottom prints hobbies.join(", "), listing all currently selected hobbies or “None” when the array is empty.
Radio buttons let users pick exactly one option from a group. All inputs in the group share the same name, but each has a distinct value. The checked one is determined by comparing state with that value.
// Radio button group controlled by a single state value
import React from "react";
function GenderSelector() {
const [gender, setGender] = React.useState("");
const handleChange = (e) => setGender(e.target.value);
return (
<div>
<h4>Select Gender</h4>
<label className="me-3">
<input
type="radio"
name="gender"
value="Male"
checked={gender === "Male"}
onChange={handleChange}
/>
Male
</label>
<label className="me-3">
<input
type="radio"
name="gender"
value="Female"
checked={gender === "Female"}
onChange={handleChange}
/>
Female
</label>
<label>
<input
type="radio"
name="gender"
value="Other"
checked={gender === "Other"}
onChange={handleChange}
/>
Other
</label>
<p className="mt-2">
Selected Gender: {gender || "None"}
</p>
</div>
);
}
export default GenderSelector;
Only one radio option can be selected at any time because all inputs share the same name="gender". Clicking an option sets the gender state to that option’s value, and the paragraph displays the currently selected gender or “None” if nothing is chosen.
You can combine checkboxes and radio buttons into a single form with a shared state object. This scales well as forms grow more complex.
// Full form combining radio buttons and multiple checkboxes
import React from "react";
function PreferencesForm() {
const [formData, setFormData] = React.useState({
gender: "",
notifications: false,
interests: [],
});
const handleCheckbox = (e) => {
const { value, checked } = e.target;
setFormData((prev) => ({
...prev,
interests: checked
? [...prev.interests, value]
: prev.interests.filter((v) => v !== value),
}));
};
const handleRadio = (e) => {
setFormData({ ...formData, gender: e.target.value });
};
const handleToggle = (e) => {
setFormData({ ...formData, notifications: e.target.checked });
};
const handleSubmit = (e) => {
e.preventDefault();
alert(JSON.stringify(formData, null, 2));
};
return (
<form onSubmit={handleSubmit}>
<h4>User Preferences</h4>
<div className="mb-3">
<strong>Gender:</strong><br />
<label className="me-3">
<input
type="radio"
name="gender"
value="Male"
checked={formData.gender === "Male"}
onChange={handleRadio}
/>
Male
</label>
<label className="me-3">
<input
type="radio"
name="gender"
value="Female"
checked={formData.gender === "Female"}
onChange={handleRadio}
/>
Female
</label>
</div>
<div className="mb-3">
<strong>Interests:</strong><br />
<label className="me-3">
<input type="checkbox" value="Coding" onChange={handleCheckbox} /> Coding
</label>
<label className="me-3">
<input type="checkbox" value="Music" onChange={handleCheckbox} /> Music
</label>
<label className="me-3">
<input type="checkbox" value="Sports" onChange={handleCheckbox} /> Sports
</label>
</div>
<div className="mb-3">
<label>
<input
type="checkbox"
checked={formData.notifications}
onChange={handleToggle}
/>
Receive Email Notifications
</label>
</div>
<button className="btn btn-primary">Save Preferences</button>
</form>
);
}
export default PreferencesForm;
This form captures gender (radio), a list of interests (multiple checkboxes), and a notification toggle (single checkbox). On submit, the complete formData object is shown via alert(JSON.stringify(...)), making it easy to see exactly what would be sent to your backend.
checked (not value) to bind checkbox and radio state.name so only one is selectable.onChange handlers.value attributes like "coding" instead of "option1" for easier processing later.name for both behavior and accessibility.JSON.stringify or formatted text.localStorage.Goal: Learn to manage checkbox and radio input states in React using controlled components, ensuring accurate and synchronized user selections across your entire form.