Skip to content

Commit 6786046

Browse files
fix(attributes-to-props): convert attrib to uncontrolled component prop
Fixes #321
1 parent dcf4718 commit 6786046

File tree

3 files changed

+33
-3
lines changed

3 files changed

+33
-3
lines changed

lib/attributes-to-props.js

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,19 @@ module.exports = function attributesToProps(attributes) {
2828

2929
// convert HTML/SVG attribute to React prop
3030
attributeNameLowerCased = attributeName.toLowerCase();
31-
propName = reactProperty.possibleStandardNames[attributeNameLowerCased];
31+
propName = getPropName(attributeNameLowerCased);
3232

3333
if (propName) {
34-
props[propName] = attributeValue;
3534
propertyInfo = reactProperty.getPropertyInfo(propName);
35+
36+
// convert attribute to uncontrolled component prop (e.g., `value` to `defaultValue`)
37+
// https://reactjs.org/docs/uncontrolled-components.html
38+
if (propName === 'checked' || propName === 'value') {
39+
propName = getPropName('default' + attributeNameLowerCased);
40+
}
41+
42+
props[propName] = attributeValue;
43+
3644
switch (propertyInfo && propertyInfo.type) {
3745
case reactProperty.BOOLEAN:
3846
props[propName] = true;
@@ -57,3 +65,13 @@ module.exports = function attributesToProps(attributes) {
5765

5866
return props;
5967
};
68+
69+
/**
70+
* Gets prop name from lowercased attribute name.
71+
*
72+
* @param {string} attributeName - Lowercased attribute name.
73+
* @return {string}
74+
*/
75+
function getPropName(attributeName) {
76+
return reactProperty.possibleStandardNames[attributeName];
77+
}

test/__snapshots__/attributes-to-props.test.js.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@ Object {
3131
"async": true,
3232
"autoFocus": true,
3333
"autoPlay": true,
34-
"checked": true,
3534
"controls": true,
3635
"default": true,
36+
"defaultChecked": true,
3737
"disabled": true,
3838
"draggable": "false",
3939
"formNoValidate": true,

test/attributes-to-props.test.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,18 @@ describe('attributesToProps with HTML attribute', () => {
103103
])('converts overloaded boolean attribute: %p', (attributes, props) => {
104104
expect(attributesToProps(attributes)).toEqual(props);
105105
});
106+
107+
it.each([
108+
[{ checked: '' }, { defaultChecked: true }],
109+
[{ checked: 'checked' }, { defaultChecked: true }],
110+
[{ value: '' }, { defaultValue: '' }],
111+
[{ value: 'foo' }, { defaultValue: 'foo' }]
112+
])(
113+
'converts form attribute to uncontrolled component property',
114+
(attributes, props) => {
115+
expect(attributesToProps(attributes)).toEqual(props);
116+
}
117+
);
106118
});
107119

108120
describe('attributesToProps with SVG attribute', () => {

0 commit comments

Comments
 (0)