@samitouri / QOS-React / commits / 39265cb892

Group warnings for unknown DOM properties (#7153)

Griffin Michl committed Jun 30, 2016 at 16:13 UTC 39265cb89266a90dcab4830133979038aeffd8e3
2 files changed +54 -15
src/renderers/dom/shared/__tests__/ReactDOMComponent-test.js
+11
@@ -163,6 +163,17 @@ describe('ReactDOMComponent', function() {
163 );
164 });
165
166 + it('should group multiple unknown prop warnings together', function() {
167 + spyOn(console, 'error');
168 + var container = document.createElement('div');
169 + ReactDOM.render(<div foo="bar" baz="qux" />, container);
170 + expect(console.error.calls.count(0)).toBe(1);
171 + expect(normalizeCodeLocInfo(console.error.calls.argsFor(0)[0])).toBe(
172 + 'Warning: Unknown props `foo`, `baz` on <div> tag. Remove these props from the element. ' +
173 + 'For details, see https://fb.me/react-unknown-prop\n in div (at **)'
174 + );
175 + });
176 +
177 it('should warn for onDblClick prop', function() {
178 spyOn(console, 'error');
179 var container = document.createElement('div');
src/renderers/dom/shared/devtools/ReactDOMUnknownPropertyDevtool.js
+43 -15
@@ -36,16 +36,16 @@ if (__DEV__) {
36 };
37 var warnedProperties = {};
38
39 - var warnUnknownProperty = function(tagName, name, debugID) {
39 + var validateProperty = function(tagName, name, debugID) {
40 if (DOMProperty.properties.hasOwnProperty(name) || DOMProperty.isCustomAttribute(name)) {
41 - return;
41 + return true;
42 }
43 if (reactProps.hasOwnProperty(name) && reactProps[name] ||
44 warnedProperties.hasOwnProperty(name) && warnedProperties[name]) {
45 - return;
45 + return true;
46 }
47 if (EventPluginRegistry.registrationNameModules.hasOwnProperty(name)) {
48 - return;
48 + return true;
49 }
50 warnedProperties[name] = true;
51 var lowerCasedName = name.toLowerCase();
@@ -75,6 +75,7 @@ if (__DEV__) {
75 standardName,
76 ReactComponentTreeDevtool.getStackAddendumByID(debugID)
77 );
78 + return true;
79 } else if (registrationName != null) {
80 warning(
81 registrationName == null,
@@ -83,22 +84,51 @@ if (__DEV__) {
84 registrationName,
85 ReactComponentTreeDevtool.getStackAddendumByID(debugID)
86 );
87 + return true;
88 } else {
89 // We were unable to guess which prop the user intended.
90 // It is likely that the user was just blindly spreading/forwarding props
91 // Components should be careful to only render valid props/attributes.
90 - warning(
91 - false,
92 - 'Unknown prop `%s` on <%s> tag. Remove this prop from the element. ' +
93 - 'For details, see https://fb.me/react-unknown-prop%s',
94 - name,
95 - tagName,
96 - ReactComponentTreeDevtool.getStackAddendumByID(debugID)
97 - );
92 + // Warning will be invoked in warnUnknownProperties to allow grouping.
93 + return false;
94 }
95 };
96 }
97
98 +var warnUnknownProperties = function(debugID, element) {
99 + var unknownProps = [];
100 + for (var key in element.props) {
101 + var isValid = validateProperty(element.type, key, debugID);
102 + if (!isValid) {
103 + unknownProps.push(key);
104 + }
105 + }
106 +
107 + var unknownPropString = unknownProps
108 + .map(prop => '`' + prop + '`')
109 + .join(', ');
110 +
111 + if (unknownProps.length === 1) {
112 + warning(
113 + false,
114 + 'Unknown prop %s on <%s> tag. Remove this prop from the element. ' +
115 + 'For details, see https://fb.me/react-unknown-prop%s',
116 + unknownPropString,
117 + element.type,
118 + ReactComponentTreeDevtool.getStackAddendumByID(debugID)
119 + );
120 + } else if (unknownProps.length > 1) {
121 + warning(
122 + false,
123 + 'Unknown props %s on <%s> tag. Remove these props from the element. ' +
124 + 'For details, see https://fb.me/react-unknown-prop%s',
125 + unknownPropString,
126 + element.type,
127 + ReactComponentTreeDevtool.getStackAddendumByID(debugID)
128 + );
129 + }
130 +};
131 +
132 function handleElement(debugID, element) {
133 if (element == null || typeof element.type !== 'string') {
134 return;
@@ -106,9 +136,7 @@ function handleElement(debugID, element) {
136 if (element.type.indexOf('-') >= 0 || element.props.is) {
137 return;
138 }
109 - for (var key in element.props) {
110 - warnUnknownProperty(element.type, key, debugID);
111 - }
139 + warnUnknownProperties(debugID, element);
140 }
141
142 var ReactDOMUnknownPropertyDevtool = {