Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

217
Views
React Radio onChange doesn’t work when deselected by other radio

So I’ve created a radio component, and i have an onChange function run, but it doesn’t trigger when the radio is deselected by another radio with the same group name, why?

Heres my code for the radio component

import { useState } from 'react';

const RadioButton = (props) => {
    const [checked, setChecked] = useState((props.checked !== undefined) ? props.checked : false);

    const handleChange = () => {
        console.log('changed to: ' + checked);
        (checked) ? props.onChecked() : props.onUnchecked();
        setChecked(!checked);
    }

    return (
        <input type="radio" className={'border-grey custom-checkbox ' + (checked ? 'checked' : 'unchecked')} name={props.groupName} onChange={handleChange}/>
    )
}

export default RadioButton;
about 4 years ago · Juan Pablo Isaza
2 answers
Answer question

0

Similar issue is discussed on OnChange event handler for radio button (INPUT type="radio") doesn't work as one value

A solution to this is to handle the changes and the states of the radio buttons on the parent element .

An example of how this is done :

const Parent = () => {
  const [buttons, setButtons] = useState([0, 0, 0]);
  const handleClick = (index) => {
    setButtons((buttons) => {
      alert(`prev radio ${buttons}`);
      // You add a condition of deselecting here if you want
      // if(buttons[index] === 1 ) return [0,0,0]
      const newButtons = [0, 0, 0];
      newButtons[index] = 1;
      alert(`new radio ${newButtons}`);
      return newButtons;
    });
  };

  return (
    <form>
      {buttons.map((_, index) => (
        <RadioButton
          handleClick={handleClick}
          key={index}
          index={index}
          checked={buttons[index]}
        />
      ))}
    </form>
  );
};

const RadioButton = ({ index, checked, handleClick }) => {

  return (
    <input
      value={"" + index}
      type="radio"
      onChange={() => handleClick(index)}
      checked={checked}
    />
  );
};

If you need some labels or other thing next to the radio button you can wrap them together ( replace RadioButton component with the component below )

const CustomInputWithOtherInfo = ({ index, checked, handleClick }) => {
  const otherInfo = [
    {
      label:"label1",
      title:"title1"     
    },
    {
      label:"label2",
      title:"title2"     
    },
    {
      label:"label3",
      title:"title3"     
    },
  ]
  return (
    <div>
      <h4>{otherInfo[index].title}</h4>
      <label>{otherInfo[index].label}</label>
      <input
        value={"" + index}
        type="radio"
        onChange={() => handleClick(index)}
        checked={checked}
      />
    </div>
  );
};

here you a can find a demo on sandbox

https://codesandbox.io/s/react-playground-forked-ik1lo0?file=/index.js:129-335

about 4 years ago · Juan Pablo Isaza Report

0

This is an over-kill. But since you asked, so here you go:

import React, { useEffect, useState } from "react";
import "./styles.css";

const arrRadios = [
  {
    id: "1",
    text: "Text1",
    checked: false
  },
  {
    id: "2",
    text: "Text2",
    checked: false
  },
  {
    id: "3",
    text: "Text3",
    checked: false
  }
];

export default function App() {
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      <RadioGroup arrRadios={arrRadios} groupId="myGroup" />
    </div>
  );
}

function RadioGroup(props) {
  const [arrRadios, setArrRadios] = useState(props.arrRadios);
  const handleChange = (e) => {
    console.log(e.target.value);
    arrRadios.forEach((a) => {
      if (a.id === e.target.value) {
        a.checked = true;
      } else {
        a.checked = false;
        dispatchEvent(new Event(`rb-deselect-${props.groupId}-${a.id}`));
      }
    });
    setArrRadios([...arrRadios]);
  };

  return (
    <div>
      {arrRadios &&
        arrRadios.map((radio) => (
          <RadioButton
            key={radio.id}
            groupId={props.groupId}
            id={radio.id}
            text={radio.text}
            checked={radio.checked}
            handleChange={handleChange}
          />
        ))}
    </div>
  );
}

function RadioButton(props) {
  const onDeselect = () => {
    console.log(`I am deselected ${props.groupId} : ${props.id}`);
  };

  useEffect(() => {
    window.addEventListener(
      `rb-deselect-${props.groupId}-${props.id}`,
      onDeselect,
      false
    );
    return () =>
      window.removeEventListener(
        `rb-deselect-${props.groupId}-${props.id}`,
        onDeselect,
        false
      );
  }, []);
  return (
    <>
      <input
        type="radio"
        name={props.groupId}
        value={props.id}
        onChange={props.handleChange}
        checked={props.checked}
      />
      <span>{props.text}</span>
    </>
  );
}

The idea is to hookup custom deselect event on the Radio button that fires (for all) when any other radio gets selected / changed.

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!