Skip to content

Commit 4548eef

Browse files
[RadioGroup] Random default name (#19890)
1 parent aa09632 commit 4548eef

File tree

3 files changed

+34
-2
lines changed

3 files changed

+34
-2
lines changed

docs/pages/api/radio-group.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ You can learn more about the difference by [reading this guide](/guides/minimizi
2626
|:-----|:-----|:--------|:------------|
2727
| <span class="prop-name">children</span> | <span class="prop-type">node</span> | | The content of the component. |
2828
| <span class="prop-name">defaultValue</span> | <span class="prop-type">any</span> | | The default `input` element value. Use when the component is not controlled. |
29-
| <span class="prop-name">name</span> | <span class="prop-type">string</span> | | The name used to reference the value of the control. |
29+
| <span class="prop-name">name</span> | <span class="prop-type">string</span> | | The name used to reference the value of the control. If you don't provide this prop, it falls back to a randomly generated name. |
3030
| <span class="prop-name">onChange</span> | <span class="prop-type">func</span> | | Callback fired when a radio button is selected.<br><br>**Signature:**<br>`function(event: object) => void`<br>*event:* The event source of the callback. You can pull out the new value by accessing `event.target.value` (string). |
3131
| <span class="prop-name">value</span> | <span class="prop-type">any</span> | | Value of the selected radio button. The DOM API casts this to a string. |
3232

packages/material-ui/src/RadioGroup/RadioGroup.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import useControlled from '../utils/useControlled';
66
import RadioGroupContext from './RadioGroupContext';
77

88
const RadioGroup = React.forwardRef(function RadioGroup(props, ref) {
9-
const { actions, children, name, value: valueProp, onChange, ...other } = props;
9+
const { actions, children, name: nameProp, value: valueProp, onChange, ...other } = props;
1010
const rootRef = React.useRef(null);
1111

1212
const [value, setValue] = useControlled({
@@ -43,6 +43,15 @@ const RadioGroup = React.forwardRef(function RadioGroup(props, ref) {
4343
}
4444
};
4545

46+
const [defaultName, setDefaultName] = React.useState();
47+
const name = nameProp || defaultName;
48+
React.useEffect(() => {
49+
// Fallback to this default name when possible.
50+
// Use the random value for client-side rendering only.
51+
// We can't use it server-side.
52+
setDefaultName(`mui-radiogroup-${Math.round(Math.random() * 1e5)}`);
53+
}, []);
54+
4655
return (
4756
<RadioGroupContext.Provider value={{ name, onChange: handleChange, value }}>
4857
<FormGroup role="radiogroup" ref={handleRef} {...other}>
@@ -67,6 +76,7 @@ RadioGroup.propTypes = {
6776
defaultValue: PropTypes.any,
6877
/**
6978
* The name used to reference the value of the control.
79+
* If you don't provide this prop, it falls back to a randomly generated name.
7080
*/
7181
name: PropTypes.string,
7282
/**

packages/material-ui/src/RadioGroup/RadioGroup.test.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,18 @@ describe('<RadioGroup />', () => {
8585
assert.strictEqual(findRadio(wrapper, 'one').props().checked, true);
8686
});
8787

88+
it('should have a default name', () => {
89+
const wrapper = mount(
90+
<RadioGroup>
91+
<Radio value="zero" />
92+
<Radio value="one" />
93+
</RadioGroup>,
94+
);
95+
96+
assert.match(findRadio(wrapper, 'zero').props().name, /^mui-radiogroup-[0-9]+/);
97+
assert.match(findRadio(wrapper, 'one').props().name, /^mui-radiogroup-[0-9]+/);
98+
});
99+
88100
describe('imperative focus()', () => {
89101
it('should focus the first non-disabled radio', () => {
90102
const actionsRef = React.createRef();
@@ -295,6 +307,16 @@ describe('<RadioGroup />', () => {
295307
setProps({ value: 'one' });
296308
expect(radioGroupRef.current).to.have.property('value', 'one');
297309
});
310+
311+
it('should have a default name from the instance', () => {
312+
const radioGroupRef = React.createRef();
313+
const { setProps } = render(<RadioGroupControlled ref={radioGroupRef} />);
314+
315+
expect(radioGroupRef.current.name).to.match(/^mui-radiogroup-[0-9]+/);
316+
317+
setProps({ name: 'anotherGroup' });
318+
expect(radioGroupRef.current).to.have.property('name', 'anotherGroup');
319+
});
298320
});
299321

300322
describe('callbacks', () => {

0 commit comments

Comments
 (0)