Back to Blog
ReactJS

Mastering React Forms: A Complete Guide to Radio Buttons

10/14/2025
5 min read
Mastering React Forms: A Complete Guide to Radio Buttons

Struggling with radio buttons in React? This in-depth guide covers controlled components, dynamic groups, best practices, and real-world examples to level up your form handling skills.

Mastering React Forms: A Complete Guide to Radio Buttons

Mastering React Forms: A Complete Guide to Radio Buttons

Taming the Radio Button: Your Definitive Guide to React Forms

If you've ever built a form in React, you know the journey. Text inputs feel straightforward, checkboxes are manageable, but then you get to radio buttons. Suddenly, you're dealing with groups, shared state, and ensuring only one is selected at a time. It can be a head-scratcher if you're new to React's way of thinking.

Fear not! In this guide, we're going to demystify radio buttons in React completely. We'll move from a basic example to a dynamic, real-world scenario, covering best practices and common pitfalls along the way. By the end, you'll be handling radio groups with the confidence of a seasoned developer.

What's So Special About Radio Buttons Anyway?

Before we dive into code, let's remember the core purpose of a radio button. Unlike checkboxes, which allow for multiple selections, radio buttons are used when you have a list of mutually exclusive options. The user must choose one, and only one, option from the group. Think of it like an old-fashioned car radio—pressing one button automatically pops out the one that was previously selected.

In HTML, we achieve this by giving all radio buttons in the same group an identical name attribute. The browser handles the state for us.

html

<!-- Plain HTML -->
<label>
  <input type="radio" name="size" value="small"> Small
</label>
<label>
  <input type="radio" name="size" value="medium"> Medium
</label>
<label>
  <input type="radio" name="size" value="large"> Large
</label>

In React, however, we don't let the DOM manage state. We take control. This is where the concept of "Controlled Components" comes in, and it's the golden rule for all form elements in React, including our friend, the radio button.

Building Your First React Radio Group: A Controlled Component

A controlled component is a form element whose value is controlled by React's state. Every keystroke, every change, is handled by a React event handler and the value is stored in the component's state.

Let's build a simple pizza size selector.

jsx

import React, { useState } from 'react';

function PizzaSizeSelector() {
  // 1. Define State to hold the current selection
  const [selectedSize, setSelectedSize] = useState('');

  // 2. Handler for when a radio button is changed
  const handleSizeChange = (event) => {
    setSelectedSize(event.target.value);
  };

  // 3. Handler for form submission
  const handleSubmit = (event) => {
    event.preventDefault();
    alert(`You selected a ${selectedSize} pizza!`);
  };

  return (
    <form onSubmit={handleSubmit}>
      <h3>Choose your pizza size:</h3>

      {/* Radio Button for Small */}
      <label>
        <input
          type="radio"
          value="small"
          checked={selectedSize === 'small'} // 🔥 The key prop!
          onChange={handleSizeChange}
        />
        Small
      </label>

      {/* Radio Button for Medium */}
      <label>
        <input
          type="radio"
          value="medium"
          checked={selectedSize === 'medium'} // 🔥
          onChange={handleSizeChange}
        />
        Medium
      </label>

      {/* Radio Button for Large */}
      <label>
        <input
          type="radio"
          value="large"
          checked={selectedSize === 'large'} // 🔥
          onChange={handleSizeChange}
        />
        Large
      </label>

      <br />
      <button type="submit">Order Pizza</button>
      <p><strong>Current Selection:</strong> {selectedSize || 'None'}</p>
    </form>
  );
}

export default PizzaSizeSelector;

Breaking Down the Magic:

  1. State (selectedSize): This single string holds the value of the currently selected radio button. It's the source of truth.

  2. onChange Handler (handleSizeChange): Whenever a user clicks a radio button, this function is called. It extracts the value from the clicked button and updates the state.

  3. The checked Prop: This is the most crucial part. For each radio input, we don't just set checked to true or false arbitrarily. We compare the button's value to the current selectedSize in state. If they match, checked becomes true. This is what gives React full control over the selection.

Leveling Up: Dynamic Radio Buttons from an Array

In real-world applications, your options won't be hardcoded. They'll likely come from an API or a configuration file. Let's create a dynamic feedback form where the rating options are loaded from an array.

jsx

import React, { useState } from 'react';

function FeedbackForm() {
  // State for the selected rating
  const [rating, setRating] = useState('');

  // This array could come from an API call or a config file
  const ratingOptions = [
    { id: 'excellent', value: '5', label: 'Excellent - 5 Stars' },
    { id: 'good', value: '4', label: 'Good - 4 Stars' },
    { id: 'average', value: '3', label: 'Average - 3 Stars' },
    { id: 'poor', value: '2', label: 'Poor - 2 Stars' },
    { id: 'terrible', value: '1', label: 'Terrible - 1 Star' },
  ];

  const handleRatingChange = (event) => {
    setRating(event.target.value);
  };

  const handleSubmit = (event) => {
    event.preventDefault();
    console.log('User Rating:', rating);
    // Here you would send the data to your backend
  };

  return (
    <form onSubmit={handleSubmit}>
      <fieldset>
        <legend>How would you rate our service?</legend>
        
        {/* Dynamically generate radio buttons */}
        {ratingOptions.map((option) => (
          <label key={option.id} htmlFor={option.id}>
            <input
              type="radio"
              id={option.id}
              value={option.value}
              checked={rating === option.value}
              onChange={handleRatingChange}
            />
            {option.label}
          </label>
        ))}
      </fieldset>
      <button type="submit">Submit Feedback</button>
      <p>You selected a rating of: <strong>{rating}</strong></p>
    </form>
  );
}

export default FeedbackForm;

This approach is incredibly powerful. To add a new rating option, you just add an object to the ratingOptions array. The form logic remains exactly the same. This is the kind of scalable, clean code that professional projects demand.

To learn professional software development courses such as Python Programming, Full Stack Development, and the MERN Stack, which dive deep into these fundamental concepts, visit and enroll today at codercrafter.in.

Best Practices and Pro-Tips

  1. Always Use <label> with htmlFor: Associating a label with its input using the htmlFor (which corresponds to the HTML for attribute) and id props is crucial for accessibility. It makes the entire text clickable, improving usability.

  2. Group with <fieldset> and <legend>: For semantic HTML and better accessibility, wrap related radio buttons in a <fieldset> and provide a description with a <legend>. This is especially helpful for screen readers.

  3. Use Descriptive value Attributes: The value is what gets sent when the form is submitted. Make it meaningful (e.g., value="user_admin" instead of value="option1").

  4. Lift State Up if Needed: If the selected radio value needs to be shared with a parent component or other parts of your app, lift the state up and pass it down via props. The onChange handler would then also be passed down from the parent.

Frequently Asked Questions (FAQs)

Q: Why is nothing selected when I click the radio buttons?
A: This is the most common issue. You've likely forgotten the checked prop or its logic is broken. Ensure you are comparing the input's value to the state variable correctly (e.g., checked={selectedOption === inputValue}).

Q: Can I have a radio button pre-selected by default?
A: Absolutely! Just initialize your state with the value of the option you want pre-selected.
const [selectedSize, setSelectedSize] = useState('medium'); // Medium will be selected by default

Q: What's the difference between checked and defaultChecked?
A: checked is for controlled components (React manages the state). defaultChecked is for uncontrolled components (the DOM manages the state) and should generally be avoided in modern React.

Q: My radio buttons aren't working dynamically. What's wrong?
A: Double-check your .map() function. Ensure each radio input has a unique key prop and that the value in your state matches the value in the options array.

Conclusion

Radio buttons in React, once you understand the pattern, are a joy to work with. The key takeaway is always to manage the selection via React state. Remember the holy trinity: a state variable, an onChange handler, and a checked prop that reflects the current state.

Start with a simple controlled component, then move to dynamic rendering from an array. Always keep accessibility and semantics in mind by using <fieldset>, <legend>, and proper <label> associations.

Mastering forms is a non-negotiable skill for any front-end developer, and radio buttons are a fundamental part of that journey. If you found this guide helpful and want to build a rock-solid foundation in modern web development, exploring a structured curriculum can make all the difference.

If you're ready to transform your coding skills and build complex, real-world applications, CoderCrafter offers comprehensive programs to get you there. To learn professional software development courses such as Python Programming, Full Stack Development, and the MERN Stack, visit and enroll today at codercrafter.in.

Related Articles

Call UsWhatsApp