Multiple Radio Buttons in React
Tags: react, javascript, radio, buttons
Published: 2022-02-25 14:24:56


 ---
title: Multiple Radio Buttons in React
published: true
description: Multiple Radio Buttons in react
tags: react, javascript, radio, buttons
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x5o09dkqfkr8sgzcwkvx.jpg
---
[Demo](https://gregpetropoulos.github.io/Radio-Buttons-Demo/)
[repo](https://github.com/GregPetropoulos/Radio-Buttons-Demo)


We have all been there staring at the same five or more radio buttons with same value or worse no value.

 All we want is each radio button to have their own state value. The confusion lies at the heart of the DOM value vs the DOM element

## Intro
I am going to code five radio buttons and show the underpinnings of react and how to handle multiple buttons in a single piece of state

## Short version: 
 - The value of an element is a primitive data type:boolean, number etc
 - The element is the actual node like  html tag, className, id etc
 - Event handler will make the connection to the state



## Getting started
 `npx create-react-app radio-buttons ` See the screenshot for the folder structure and code. I cleaned up the boilerplate and added `useState` go [here](https://github.com/GregPetropoulos/Radio-Buttons-Demo) for the repo.

![React scaffold](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/15xdq8q77dxyxm5fa1f7.png)
 


### App.js
```
const App = () => {
  return (
    <div className='App'>
      <h1>Radio Journey</h1>
    </div>
  );
};

export default App;

```
 

### Index.js
```
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);

```
### Index.css
Style for style points on your own or see mine later in the demo  [Styles](#styles)

Ok now that we have the basic set up lets code through it.

We need to add `state` and a radio button such as
```
import { useState } from 'react';

const App = () => {
  //STATE
  const [isRadio, setIsRadio] = useState(5);

  return (
    <div className='App'>
      <h1>Radio Journey</h1>
      <ul>
        <li>
          <input />
          <label>1</label>
        </li>
      </ul>
    </div>
  );
};

export default App;
```
## Next the `<input/>` and `<label/>` need a few props like so
```
import { useState } from 'react';

const App = () => {
  
//STATE
  const [isRadio, setIsRadio] = useState(5);

  
  return (
    <div className='App'>
      <h1>Radio Journey</h1>
      <ul>
        <li>
          <input
            type='radio'
            id='radio1'
            value='1'
            onChange={handleChange}
            checked={isRadio === 1}
          />
          <label htmlFor='num1'>1</label>
        </li>
      </ul>
    </div>
  );
};
``` 
## Styles <a name="styles"></a>
add style to get a visual interface of whats going on. Add this to your index.css
```
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

body {
  font-family: 'Courier New', Courier, monospace;
  background-color: #090c57cb;
  color: #fff;
  line-height: 1.8;
}

ul {
  list-style: none;
}
h1 {
  text-align: center;
}
.container {
  max-width: 768px;
  margin: auto;
  padding: 0 20px;
}

input {
  flex-grow: 2;
  border: none;
  font-size: 16px;
}

input:focus {
  outline: none;
}

.radios {
  display: flex;
  align-items: center;
  justify-content: space-around;
  margin: 30px 0 40px;
}

.radios li {
  position: relative;
  background: #f4f4f4;
  width: 50px;
  height: 50px;
  padding: 10px;
  text-align: center;
  border-radius: 50%;
  font-size: 19px;
  border: 1px #eee solid;
  transition: 0.3s;
}
li label {
  position: absolute;
  top: 110%;
  left: 0;
  width: 50px;
  height: 50px;
  padding: 10px;
  border-radius: 50%;
}

.radios li:hover {
  background: #f00303;
  color: #fff;
}

[type='radio'] {
  opacity: 0;
}

[type='radio']:checked ~ label {
  background: #f00303;
  color: #fff;
}
```
## Should look like this
![UI](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6k70vtebkkqo1z1c02lo.png)
 
 

The `<input/>` has everything it needs and we have styles. Next address the `handleChange` and add four more radio buttons.
```
import { useState } from 'react';

const App = () => {
  //STATE
  const [isRadio, setIsRadio] = useState(5);

  // HANDLE THE ONCHANGE HERE

  const handleChange = (e) => {
    // string passed in
    // a string returned by default
    console.log(e.currentTarget.value);
    // add + to the event to make the value a number
    setIsRadio(+e.currentTarget.value);
  };

  return (
    <div className='App'>
      <h1>Radio Journey</h1>
      <ul className='radios'>
        <li>
          <input
            type='radio'
            id='radio1'
            value='1'
            onChange={handleChange}
            checked={isRadio === 1}
          />
          <label htmlFor='num1'>1</label>
        </li>
        <li>
          <input
            type='radio'
            id='radio2'
            value='2'
            onChange={handleChange}
            checked={isRadio === 2}
          />
          <label htmlFor='num2'>2</label>
        </li>
        <li>
          <input
            type='radio'
            id='radio3'
            value='3'
            onChange={handleChange}
            checked={isRadio === 3}
          />
          <label htmlFor='num3'>3</label>
        </li>
        <li>
          <input
            type='radio'
            id='radio4'
            value='4'
            onChange={handleChange}
            checked={isRadio === 4}
          />
          <label htmlFor='num4'>4</label>
        </li>
        <li>
          <input
            type='radio'
            id='radio5'
            value='5'
            onChange={handleChange}
            checked={isRadio === 5}
          />
          <label htmlFor='num5'>5</label>
        </li>
      </ul>
```
## You should have this in your browser:
![5 Radios](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z3rd8uwnxvi26ggadan2.png)
##### Notice the console.log(e.currentTarget.value)

Here is definition of the currentTarget [Docs here](https://developer.mozilla.org/en-US/docs/Web/API/Event/currentTarget):
"The currentTarget read-only property of the Event interface identifies the current target for the event, as the event traverses the DOM."

Let's run back through it. We have five radio buttons each one has a string value captured by the handleChange function when clicked. The string value needs to be changed to a number by adding the '+' sign in front of the e like so `setIsRadio(+e.currentTarget.value);`


Now that the clicked value is a number it gets updated to the state and `isRadio` is a new value. The `checked` prop is a unique identifier for the state to match to 'Hey checked your number value matches let's make you the star of the show'.

click event > handleChange > updates state > checked made it to the show. 

Like always confirm with dev tools:
![Dev tools](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/33k4yks6uvcp8t24wd9t.png)
  
Conclusion
In this demo my intent was to show how to effectively utilize one piece of state with hooks and multiple radio buttons in code. The console and dev tools confirmed the UI is matching the state changes. I hope this demo was helpful. This demo is could easily be used to create your next radio button component and be further optimized.

 * There are a few ways to handle multiple radio buttons especially as they get nested into components which is out of the scope of this demo.   



## Links :link:
[useState](https://reactjs.org/docs/hooks-reference.html#functional-updates)
[Input](https://reactjs.org/docs/forms.html#handling-multiple-inputs)
[Checked](https://reactjs.org/docs/dom-elements.html#checked)
[currentTarget](https://developer.mozilla.org/en-US/docs/Web/API/Event/currentTarget)

:heart::heart::heart:

## Social
[Twitter](https://twitter.com/GregoriosPetro1)
[Linkedin](https://www.linkedin.com/in/greg-petropoulos/)
[Portfolio](https://gregpetropoulos.dev/)
[Github](https://github.com/GregPetropoulos)


:metal:
Thank you for reading happy coding!

**Github Repo**
{% github GregPetropoulos/Radio-Buttons-Demo  no-readme %}