Introducing PrimeReact v11-alpha 🎉Discover Now

useRadioButton

Hooks that manage radio button and radio button group state, checked logic, and ARIA attributes.

basic-demo

Usage#

import { useRadioButton } from '@primereact/headless/radiobutton';
import { useRadioButtonGroup } from '@primereact/headless/radiobuttongroup';
const group = useRadioButtonGroup({ defaultValue: 'a' });
const { rootProps, inputProps, boxProps, indicatorProps, state } = useRadioButton({
    value: 'a',
    checked: group.state.value === 'a',
    onCheckedChange: (e) => group.updateChange({ ...e, value: 'a' })
});
 
<div {...rootProps}>
    <input {...inputProps} className="sr-only" />
    <div {...boxProps}>{state.checked && <span {...indicatorProps} />}</div>
</div>;

useRadioButton manages checked state for a single option while useRadioButtonGroup manages the shared value across a group. See Primitive for a component-based API.

Features#

  • Composable parts — spreads props onto root, input, box, and indicator elements for full visual control
  • Group coordination — useRadioButtonGroup holds the selected value and exposes updateChange for child radios
  • Controlled or uncontrolled — drive via checked/onCheckedChange or let the hook manage state from defaultChecked
  • Accessible primitives — hidden native input keeps focus management and keyboard semantics intact
  • State flags — disabled and readOnly emit the appropriate ARIA and data-* attributes

Working with callbacks#

Controlled radio#

Pass checked and onCheckedChange to own the state externally — typical when validation lives outside the component.

const [checked, setChecked] = React.useState(true);
 
useRadioButton({
    checked,
    onCheckedChange: (e) => setChecked(e.checked)
});

The callback receives { originalEvent, checked } where checked is the new boolean.

Group with shared value#

useRadioButtonGroup owns the selected value; each radio derives checked and forwards events through updateChange.

const group = useRadioButtonGroup({ defaultValue: 'a' });
 
const radioA = useRadioButton({
    value: 'a',
    checked: group.state.value === 'a',
    onCheckedChange: (e) => group.updateChange({ ...e, value: 'a' })
});

Controlled group#

Lift the group value when you need to react to changes, persist it, or reset from parent state.

const [value, setValue] = React.useState<unknown>('a');
 
const group = useRadioButtonGroup({
    value,
    onValueChange: (e) => setValue(e.value)
});

Read-only selection#

Use readOnly to keep the radio focusable (screen readers still announce it) but prevent state changes — useful for review screens.

useRadioButton({ readOnly: true });

Styling with data attributes#

Every prop object includes data-scope="radiobutton" and a data-part attribute. State-dependent attributes are added automatically.

ScopePartStates
radiobuttonrootdata-checked, data-disabled
radiobuttonboxdata-checked
radiobuttonindicatordata-checked
[data-scope='radiobutton'][data-part='box'] {
    width: 1.125rem;
    height: 1.125rem;
    border: 1px solid #ccc;
    border-radius: 9999px;
}
 
[data-scope='radiobutton'][data-part='box'][data-checked] {
    background: var(--p-primary-color);
    border-color: var(--p-primary-color);
}
 
[data-scope='radiobutton'][data-part='indicator'][data-checked] {
    width: 0.625rem;
    height: 0.625rem;
    border-radius: 9999px;
    background: white;
}
 
[data-scope='radiobutton'][data-part='root'][data-disabled] {
    opacity: 0.5;
    cursor: not-allowed;
}

API#

useRadioButton#

NameTypeDefault
checkedboolean—
When present, it specifies the input's checked state.
defaultCheckedboolean—
The default value for the input when not controlled by `checked` and `onCheckedChange` .
inputIdstring—
Identifier of the underlying input element.
valueunknown—
Value of the radio button.
namestring—
The name attribute of the input, resolved from group context if available.
disabledbooleanfalse
When present, it specifies that the element should be disabled.
readOnlybooleanfalse
When present, it specifies that an input field is read-only.
requiredbooleanfalse
When present, it specifies that the element is required.
tabIndexnumber—
Tab index for keyboard navigation.
invalidbooleanfalse
When present, it specifies that the component should have invalid state style.
ariaLabelledbystring—
Establishes relationships between the component and label(s) where its value should be one or more element IDs.
ariaLabelstring—
Establishes a string value that labels the component.
onFocus(event: FocusEvent<HTMLInputElement>) => void—
Callback function that is called when the radio button is focused.
onBlur(event: FocusEvent<HTMLInputElement>) => void—
Callback function that is called when the radio button loses focus.
onCheckedChange(event: useRadioButtonChangeEvent) => void—
Callback fired when the radio button's checked state changes.

useRadioButtonGroup#

NameTypeDefault
valueunknown—
Value of the radio button group.
defaultValueunknown—
The default value of the radio button group.
onValueChange(event: useRadioButtonGroupValueChangeEvent) => void—
Callback fired when the radio button group's value state changes.

Accessibility#

Arrow keys move between radios in the same group, and the focused radio is automatically selected. See Primitive for full WAI-ARIA compliance details.