Remove initOption special case (#26595)
This traces back to https://github.com/facebook/react/pull/6449 and then another before that. I think that back then we favored the property over the attribute, and setting the property wouldn't be enough. However, the default path for these are now using attributes if we don't special case it. So we don't need it. The only difference is that we currently have a divergence for symbol/function behavior between controlled values that use the getToStringValue helpers which treat them as empty string, where as everywhere else they're treated as null/missing. Since this comes with a warning and is a weird error case, it's probably fine to change.
Sebastian Markbåge committed
Apr 11, 2023 at 12:39 UTC
343a45ffa48065e60699bbe68f82d7b62fa02840
3 files changed
+19
-21
packages/react-dom-bindings/src/client/ReactDOMComponent.js
+1
-2
@@ -32,7 +32,7 @@ import {
32
updateInput,
33
restoreControlledInputState,
34
} from './ReactDOMInput';
35
-import {initOption, validateOptionProps} from './ReactDOMOption';
35
+import {validateOptionProps} from './ReactDOMOption';
36
import {
37
validateSelectProps,
38
initSelect,
@@ -995,7 +995,6 @@ export function setInitialProperties(
995
}
996
}
997
}
998
- initOption(domElement, props);
998
return;
999
}
1000
case 'dialog': {
packages/react-dom-bindings/src/client/ReactDOMOption.js
-8
@@ -8,7 +8,6 @@
8
*/
9
10
import {Children} from 'react';
11
-import {getToStringValue, toString} from './ToStringValue';
11
12
let didWarnSelectedSetOnOption = false;
13
let didWarnInvalidChild = false;
@@ -59,10 +58,3 @@ export function validateOptionProps(element: Element, props: Object) {
58
}
59
}
60
}
62
-
63
-export function initOption(element: Element, props: Object) {
64
- // value="" should make a value attribute (#6219)
65
- if (props.value != null) {
66
- element.setAttribute('value', toString(getToStringValue(props.value)));
67
- }
68
-}
packages/react-dom/src/__tests__/ReactDOMSelect-test.js
+18
-11
@@ -9,6 +9,13 @@
9
10
'use strict';
11
12
+// Fix JSDOM. setAttribute is supposed to throw on things that can't be implicitly toStringed.
13
+const setAttribute = Element.prototype.setAttribute;
14
+Element.prototype.setAttribute = function (name, value) {
15
+ // eslint-disable-next-line react-internal/safe-string-coercion
16
+ return setAttribute.call(this, name, '' + value);
17
+};
18
+
19
describe('ReactDOMSelect', () => {
20
let React;
21
let ReactDOM;
@@ -849,7 +856,7 @@ describe('ReactDOMSelect', () => {
856
});
857
858
describe('When given a Symbol value', () => {
852
- it('treats initial Symbol value as an empty string', () => {
859
+ it('treats initial Symbol value as missing', () => {
860
let node;
861
862
expect(() => {
@@ -862,10 +869,10 @@ describe('ReactDOMSelect', () => {
869
);
870
}).toErrorDev('Invalid value for prop `value`');
871
865
- expect(node.value).toBe('');
872
+ expect(node.value).toBe('A Symbol!');
873
});
874
868
- it('treats updated Symbol value as an empty string', () => {
875
+ it('treats updated Symbol value as missing', () => {
876
let node;
877
878
expect(() => {
@@ -888,7 +895,7 @@ describe('ReactDOMSelect', () => {
895
</select>,
896
);
897
891
- expect(node.value).toBe('');
898
+ expect(node.value).toBe('A Symbol!');
899
});
900
901
it('treats initial Symbol defaultValue as an empty string', () => {
@@ -904,7 +911,7 @@ describe('ReactDOMSelect', () => {
911
);
912
}).toErrorDev('Invalid value for prop `value`');
913
907
- expect(node.value).toBe('');
914
+ expect(node.value).toBe('A Symbol!');
915
});
916
917
it('treats updated Symbol defaultValue as an empty string', () => {
@@ -930,12 +937,12 @@ describe('ReactDOMSelect', () => {
937
</select>,
938
);
939
933
- expect(node.value).toBe('');
940
+ expect(node.value).toBe('A Symbol!');
941
});
942
});
943
944
describe('When given a function value', () => {
938
- it('treats initial function value as an empty string', () => {
945
+ it('treats initial function value as missing', () => {
946
let node;
947
948
expect(() => {
@@ -948,7 +955,7 @@ describe('ReactDOMSelect', () => {
955
);
956
}).toErrorDev('Invalid value for prop `value`');
957
951
- expect(node.value).toBe('');
958
+ expect(node.value).toBe('A function!');
959
});
960
961
it('treats initial function defaultValue as an empty string', () => {
@@ -964,7 +971,7 @@ describe('ReactDOMSelect', () => {
971
);
972
}).toErrorDev('Invalid value for prop `value`');
973
967
- expect(node.value).toBe('');
974
+ expect(node.value).toBe('A function!');
975
});
976
977
it('treats updated function value as an empty string', () => {
@@ -990,7 +997,7 @@ describe('ReactDOMSelect', () => {
997
</select>,
998
);
999
993
- expect(node.value).toBe('');
1000
+ expect(node.value).toBe('A function!');
1001
});
1002
1003
it('treats updated function defaultValue as an empty string', () => {
@@ -1016,7 +1023,7 @@ describe('ReactDOMSelect', () => {
1023
</select>,
1024
);
1025
1019
- expect(node.value).toBe('');
1026
+ expect(node.value).toBe('A function!');
1027
});
1028
});
1029