How to Use Radio Buttons in Reactjs

How to use radio buttons in ReactJS?

Any changes to the rendering should be change via the state or props (react doc).

So here I register the event of the input, and then change the state, which will then trigger the render to show on the footer.

var SearchResult = React.createClass({
getInitialState: function () {
return {
site: '',
address: '',
};
},
onSiteChanged: function (e) {
this.setState({
site: e.currentTarget.value,
});
},

onAddressChanged: function (e) {
this.setState({
address: e.currentTarget.value,
});
},

render: function () {
var resultRows = this.props.data.map(function (result) {
return (
<tbody>
<tr>
<td>
<input
type="radio"
name="site_name"
value={result.SITE_NAME}
checked={this.state.site === result.SITE_NAME}
onChange={this.onSiteChanged}
/>
{result.SITE_NAME}
</td>
<td>
<input
type="radio"
name="address"
value={result.ADDRESS}
checked={this.state.address === result.ADDRESS}
onChange={this.onAddressChanged}
/>
{result.ADDRESS}
</td>
</tr>
</tbody>
);
}, this);
return (
<table className="table">
<thead>
<tr>
<th>Name</th>
<th>Address</th>
</tr>
</thead>
{resultRows}
<tfoot>
<tr>
<td>chosen site name {this.state.site} </td>
<td>chosen address {this.state.address} </td>
</tr>
</tfoot>
</table>
);
},
});

jsbin

How to handle group radio button in React JS - FUNCTIONAL COMPONENT

To select only one option in the group of radio buttons you need to use same name in every input of radio. To save your choice we can use useState. Here is the complete example:

import React, { useState } from "react";

function Demo() {
const [gender, setGender] = useState("Male");

function onChangeValue(event) {
setGender(event.target.value);
console.log(event.target.value);
}

return (
<div onChange={onChangeValue}>
<input type="radio" value="Male" name="gender" checked={gender === "Male"} /> Male
<input type="radio" value="Female" name="gender" checked={gender === "Female"}/> Female
<input type="radio" value="Other" name="gender" checked={gender === "Other"} /> Other
</div>
);
}

export default Demo;

How to handle multiple radio button in map function in reactjs?

You can set name to your input radio like this:

<input style={{width:'20px'}} type='radio' name='is-policy'></input>

for next radio group:

<input style={{width:'20px'}} type='radio' name='is-management'></input>

Note: The radio group must have share the same name (the value of the name attribute) to be treated as a group. Once the radio group is created, selecting any radio button in that group automatically deselects any other selected radio button in the same group. You can have as many radio groups on a page as you want, as long as each group has its own name. source

Radio buttons with react-hook-form

Since rain, wind, sun should be assign to the same value we need to pass same params to register function as below

function App() {
const {register, handleSubmit} = useForm();

function onSubmitButton(data) {
console.log(data)
}

return (
<>
<h1>Order weather</h1>
<form onSubmit={handleSubmit(onSubmitButton)}>
<input
{...register("fullName")}
type="text"
placeholder="Name and surname"
id="name"
/>
<input
{...register("city")}
type="text"
placeholder="City"
id="city"
/>
<p>I would like to:</p>
<label htmlFor="field-rain">
<input
{...register("weather")}
type="radio"
value="rain"
id="field-rain"
/>
Rain
</label>
<label htmlFor="field-wind">
<input
{...register("weather")}
type="radio"
value="wind"
id="field-wind"
/>
Lots of wind
</label>
<label htmlFor="field-sun">
<input
{...register("weather")}
type="radio"
value="sun"
id="field-sun"
/>
Sunny
</label>
<button type="submit">
Send
</button>
</form>
</>
);
}

export default App;

I hope this will fix the issue.

Navigating through different pages with onClick & radio buttons - React.js

Issue

The issue is that React state updates aren't immediately processed, they are enqueued and asynchronously processed later. The formData state update from handleChange is not yet available when test function is called as the same time.

Solution

It seems you want the act of navigation to be an effect of selecting from the radio buttons. Move the test function logic into an useEffect hook to issue the imperative navigation.

Example:

export default function DisplayHomeOptions() {
const navigate = useNavigate();

const [formData, setFormData] = React.useState({
location: "",
selector: ""
});

useEffect(() => {
const { location, selector } = formData;
switch (true) {
case location === "National" && selector === "Polls":
navigate("/np");
break;

case location === "Global" && selector === "Questions":
navigate("/gq");
break;

case location === "Global" && selector === "Polls":
navigate("/gp");
break;

case location === "National" && selector === "Messages":
navigate("/nm");
break;

case location === "National" && selector === "Questions":
navigate("/nq");
break;

case location === "Global" && selector === "Messages":
navigate("/gm");
break;

default:
// ignore
}
}, [formData]);

function handleChange(event) {
const { name, value, type, checked } = event.target;
setFormData((prevFormData) => {
return {
...prevFormData,
[name]: type === "checkbox" ? checked : value
};
});
}

return (
<div>
<fieldset>
<legend>Option #1</legend>
<input
type="radio"
name="location"
value="Global"
onChange={handleChange}
/>

<label htmlFor="Global">Global</label>
<input
type="radio"
name="location"
value="National"
onChange={handleChange}
/>
<label htmlFor="National">National</label>
</fieldset>

<fieldset>
<legend>Option #2</legend>
<input
type="radio"
name="selector"
value="Messages"
onChange={handleChange}
/>
<label htmlFor="Messages">Messages</label>
<input
type="radio"
name="selector"
value="Questions"
onChange={handleChange}
/>
<label htmlFor="Questions">Questions</label>
<input
type="radio"
name="selector"
value="Polls"
onChange={handleChange}
/>
<label htmlFor="Polls">Polls</label>
</fieldset>
</div>
);
}

An optimization may be to declare a Map of target paths from the location and selector values as keys.

const navTarget = {
National: {
Messages: "/nm",
Polls: "/np",
Questions: "/nq",
},
Global: {
Messages: "/gm",
Polls: "/gp",
Questions: "/gq",
}
}

...

useEffect(() => {
const { location, selector } = formData;
if (location && selector) {
const target = navTarget[location][selector];
if (target) {
navigate(target);
}
}
}, [formData]);

Radio Button with React

I think your problem is with the name attribute on your input. You give each input a different name so you make each input belong to a different group. All radio inputs must have the same name (see here) or no name attribute at all.

BTW, in most cases you don't need to put an id attribute when writing React code.

Also the useState function accepts the default state as parameter and not the type.

See this simple code snippet:

class Root extends React.Component {
render() {
return (
<div>
Group 1: <RadioGroup />
Group 2: <RadioGroup />
</div>
);
}
}

const RadioGroup = () =>{
const [active, setActive] = React.useState(0);
return (
<div>
<input type="radio" checked={active==0} onClick={() => setActive(0)} />
<input type="radio" checked={active==1} onClick={() => setActive(1)} />
</div>
);
}

ReactDOM.render(
<Root />,
document.getElementById('container')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>

<div id="container"></div>

Radio button style changes when clicked with React Hooks

One option is a custom Radio element that allows you to represent your radio buttons however you like. In this example we use two emoji, but you could use images, or SVG if you wanted.

function Radio({ checked, onClick, children, on = "✔️", off = "quot; }) {
return <div className="radio" onClick={onClick}>
{checked ? on : off } {children}
</div>
}

We can use the Radio elements in our app like this.

function App() {
const [radio, selectRadio] =
useRadio(["paystack", "paypal", "wallet"], "paystack")
return <div>
<Radio checked={radio == "paystack"} onClick={selectRadio("paystack")}>
Paystack (Debit/Credit Card)
</Radio>
{/* more radio options ...*/}
</div>
}

This is made possible by writing useRadio which encodes the radio group logic nicely in a custom hook.

function useRadio(validStates, initState) {
const [state, setState] = React.useState(initState)
return [
state,
value => event =>
validStates.includes(value)
? setState(value)
: console.error(`invalid option: ${value}`)
]
}

Here's a minimal, verifiable example. Run it below and click some radio buttons to see the application state change.

function App() {
const [radio, selectRadio] = useRadio(["paystack", "paypal", "wallet"], "paystack")
return <div>
<Radio checked={radio == "paystack"} onClick={selectRadio("paystack")}>
Paystack (Debit/Credit Card)
</Radio>
<Radio checked={radio == "wallet"} onClick={selectRadio("wallet")}>
Pay with Wallet
</Radio>
<Radio checked={radio == "paypal"} onClick={selectRadio("paypal")}>
PayPal
</Radio>
<pre>{JSON.stringify({paymentOption: radio}, null, 2)}</pre>
</div>
}

function Radio({ checked, onClick, children, on = "✔️", off = " }) {
return <div className="radio" onClick={onClick}>
{checked ? on : off } {children}
</div>
}

function useRadio(validStates, initState) {
const [state, setState] = React.useState(initState)
return [
state,
value => event =>
validStates.includes(value)
? setState(value)
: console.error(`invalid option: ${value}`)
]
}

ReactDOM.render(<App/>, document.querySelector("#app"))
.radio { cursor: pointer; }
pre { padding: 0.5rem; background-color: #ffc; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.14.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.14.0/umd/react-dom.production.min.js"></script>
<div id="app"></div>

How to use react hook form's Controller with radio buttons

  1. Use WrapperRadio in RegistrationForm - you should pass in a default value.

       <form onSubmit={onSubmit}>
    <WrapperRadio
    control={control}
    name="radioSelection"
    label="This is a label"
    value={true}
    />
    </form>
  2. Using Controller in WrapperRadio

            return (
    <div>
    <Controller
    control={control}
    name={name}
    render={({ field: {onChange, ...props} }) =>
    <RadioButton
    onChange={e => onChange(e.target.checked)}
    {...props} label={label} />}
    />
    </div>



Related Topics



Leave a reply



Submit