Warn when "false" or "true" is the value of a boolean DOM prop (#13372)
* Warn when the string "false" is the value of a boolean DOM prop * Only warn on exact case match for "false" in DOM boolean props * Warn on string "true" as well as "false" in DOM boolean props * Clarify warnings on "true" / "false" values in DOM boolean props
Moti Zilberman committed
Aug 14, 2018 at 20:51 UTC
2c59076d26e6b5ffb39dab82e1cc0decb6ed30ae
3 files changed
+53
-1
packages/react-dom/src/__tests__/ReactDOMComponent-test.js
+28
@@ -2506,6 +2506,34 @@ describe('ReactDOMComponent', () => {
2506
});
2507
});
2508
2509
+ describe('Boolean attributes', function() {
2510
+ it('warns on the ambiguous string value "false"', function() {
2511
+ let el;
2512
+ expect(() => {
2513
+ el = ReactTestUtils.renderIntoDocument(<div hidden="false" />);
2514
+ }).toWarnDev(
2515
+ 'Received the string `false` for the boolean attribute `hidden`. ' +
2516
+ 'The browser will interpret it as a truthy value. ' +
2517
+ 'Did you mean hidden={false}?',
2518
+ );
2519
+
2520
+ expect(el.getAttribute('hidden')).toBe('');
2521
+ });
2522
+
2523
+ it('warns on the potentially-ambiguous string value "true"', function() {
2524
+ let el;
2525
+ expect(() => {
2526
+ el = ReactTestUtils.renderIntoDocument(<div hidden="true" />);
2527
+ }).toWarnDev(
2528
+ 'Received the string `true` for the boolean attribute `hidden`. ' +
2529
+ 'Although this works, it will not work as expected if you pass the string "false". ' +
2530
+ 'Did you mean hidden={true}?',
2531
+ );
2532
+
2533
+ expect(el.getAttribute('hidden')).toBe('');
2534
+ });
2535
+ });
2536
+
2537
describe('Hyphenated SVG elements', function() {
2538
it('the font-face element is not a custom element', function() {
2539
let el;
packages/react-dom/src/__tests__/ReactDOMInput-test.js
+1
-1
@@ -444,7 +444,7 @@ describe('ReactDOMInput', () => {
444
445
it('should take `defaultValue` when changing to uncontrolled input', () => {
446
const node = ReactDOM.render(
447
- <input type="text" value="0" readOnly="true" />,
447
+ <input type="text" value="0" readOnly={true} />,
448
container,
449
);
450
expect(node.value).toBe('0');
packages/react-dom/src/shared/ReactDOMUnknownPropertyHook.js
+24
@@ -13,6 +13,7 @@ import warning from 'shared/warning';
13
14
import {
15
ATTRIBUTE_NAME_CHAR,
16
+ BOOLEAN,
17
RESERVED,
18
shouldRemoveAttributeWithWarning,
19
getPropertyInfo,
@@ -226,6 +227,29 @@ if (__DEV__) {
227
return false;
228
}
229
230
+ // Warn when passing the strings 'false' or 'true' into a boolean prop
231
+ if (
232
+ (value === 'false' || value === 'true') &&
233
+ propertyInfo !== null &&
234
+ propertyInfo.type === BOOLEAN
235
+ ) {
236
+ warning(
237
+ false,
238
+ 'Received the string `%s` for the boolean attribute `%s`. ' +
239
+ '%s ' +
240
+ 'Did you mean %s={%s}?',
241
+ value,
242
+ name,
243
+ value === 'false'
244
+ ? 'The browser will interpret it as a truthy value.'
245
+ : 'Although this works, it will not work as expected if you pass the string "false".',
246
+ name,
247
+ value,
248
+ );
249
+ warnedProperties[name] = true;
250
+ return true;
251
+ }
252
+
253
return true;
254
};
255
}