@samitouri / QOS-React-2 / commits / eee04b19e1

Add monitor module for logging instrumentation

This adds an instrumentation hook for logging so that we can monitor invalid API usage before we're ready to issue a warning. I took the opportunity to update some console.warns to use the warning module instead. The remaining console.warns will be replaced by the warning module after we've cleaned up the callsites.

Sebastian Markbage committed Mar 3, 2014 at 09:39 UTC eee04b19e1866fdf5fb40298dbbfe7804b691d26
8 files changed +65 -49
src/browser/dom/DOMPropertyOperations.js
+5 -5
@@ -23,6 +23,7 @@ var DOMProperty = require('DOMProperty');
23
24 var escapeTextForBrowser = require('escapeTextForBrowser');
25 var memoizeStringOnly = require('memoizeStringOnly');
26 +var warning = require('warning');
27
28 function shouldIgnoreValue(name, value) {
29 return value == null ||
@@ -57,11 +58,10 @@ if (__DEV__) {
58
59 // For now, only warn when we have a suggested correction. This prevents
60 // logging too much when using transferPropsTo.
60 - if (standardName != null) {
61 - console.warn(
62 - 'Unknown DOM property ' + name + '. Did you mean ' + standardName + '?'
63 - );
64 - }
61 + warning(
62 + standardName == null,
63 + 'Unknown DOM property ' + name + '. Did you mean ' + standardName + '?'
64 + );
65
66 };
67 }
src/browser/dom/components/LinkedValueUtils.js
+22 -23
@@ -22,6 +22,7 @@
22 var ReactPropTypes = require('ReactPropTypes');
23
24 var invariant = require('invariant');
25 +var warning = require('warning');
26
27 var hasReadOnlyValue = {
28 'button': true,
@@ -84,33 +85,31 @@ var LinkedValueUtils = {
85 propTypes: {
86 value: function(props, propName, componentName) {
87 if (__DEV__) {
87 - if (props[propName] &&
88 - !hasReadOnlyValue[props.type] &&
89 - !props.onChange &&
90 - !props.readOnly &&
91 - !props.disabled) {
92 - console.warn(
93 - 'You provided a `value` prop to a form field without an ' +
94 - '`onChange` handler. This will render a read-only field. If ' +
95 - 'the field should be mutable use `defaultValue`. Otherwise, ' +
96 - 'set either `onChange` or `readOnly`.'
97 - );
98 - }
88 + warning(
89 + !props[propName] ||
90 + hasReadOnlyValue[props.type] ||
91 + props.onChange ||
92 + props.readOnly ||
93 + props.disabled,
94 + 'You provided a `value` prop to a form field without an ' +
95 + '`onChange` handler. This will render a read-only field. If ' +
96 + 'the field should be mutable use `defaultValue`. Otherwise, ' +
97 + 'set either `onChange` or `readOnly`.'
98 + );
99 }
100 },
101 checked: function(props, propName, componentName) {
102 if (__DEV__) {
103 - if (props[propName] &&
104 - !props.onChange &&
105 - !props.readOnly &&
106 - !props.disabled) {
107 - console.warn(
108 - 'You provided a `checked` prop to a form field without an ' +
109 - '`onChange` handler. This will render a read-only field. If ' +
110 - 'the field should be mutable use `defaultChecked`. Otherwise, ' +
111 - 'set either `onChange` or `readOnly`.'
112 - );
113 - }
103 + warning(
104 + !props[propName] ||
105 + props.onChange ||
106 + props.readOnly ||
107 + props.disabled,
108 + 'You provided a `checked` prop to a form field without an ' +
109 + '`onChange` handler. This will render a read-only field. If ' +
110 + 'the field should be mutable use `defaultChecked`. Otherwise, ' +
111 + 'set either `onChange` or `readOnly`.'
112 + );
113 }
114 },
115 onChange: ReactPropTypes.func
src/browser/dom/components/ReactDOMOption.js
+8 -7
@@ -22,6 +22,8 @@ var ReactBrowserComponentMixin = require('ReactBrowserComponentMixin');
22 var ReactCompositeComponent = require('ReactCompositeComponent');
23 var ReactDOM = require('ReactDOM');
24
25 +var warning = require('warning');
26 +
27 // Store a reference to the <option> `ReactDOMComponent`.
28 var option = ReactDOM.option;
29
@@ -35,13 +37,12 @@ var ReactDOMOption = ReactCompositeComponent.createClass({
37
38 componentWillMount: function() {
39 // TODO (yungsters): Remove support for `selected` in <option>.
38 - if (this.props.selected != null) {
39 - if (__DEV__) {
40 - console.warn(
41 - 'Use the `defaultValue` or `value` props on <select> instead of ' +
42 - 'setting `selected` on <option>.'
43 - );
44 - }
40 + if (__DEV__) {
41 + warning(
42 + this.props.selected == null,
43 + 'Use the `defaultValue` or `value` props on <select> instead of ' +
44 + 'setting `selected` on <option>.'
45 + );
46 }
47 },
48
src/browser/dom/components/ReactDOMTextarea.js
+4 -1
@@ -28,6 +28,8 @@ var ReactDOM = require('ReactDOM');
28 var invariant = require('invariant');
29 var merge = require('merge');
30
31 +var warning = require('warning');
32 +
33 // Store a reference to the <textarea> `ReactDOMComponent`.
34 var textarea = ReactDOM.textarea;
35
@@ -57,7 +59,8 @@ var ReactDOMTextarea = ReactCompositeComponent.createClass({
59 var children = this.props.children;
60 if (children != null) {
61 if (__DEV__) {
60 - console.warn(
62 + warning(
63 + false,
64 'Use the `defaultValue` or `value` props instead of setting ' +
65 'children on <textarea>.'
66 );
src/core/ReactComponent.js
+3
@@ -25,6 +25,7 @@ var ReactUpdates = require('ReactUpdates');
25 var invariant = require('invariant');
26 var keyMirror = require('keyMirror');
27 var merge = require('merge');
28 +var monitorCodeUse = require('monitorCodeUse');
29
30 /**
31 * Every React component is in one of these life cycles.
@@ -116,6 +117,7 @@ function validateExplicitKey(component) {
117 }
118
119 message += ' See http://fb.me/react-warning-keys for more information.';
120 + monitorCodeUse('react_key_warning');
121 console.warn(message);
122 }
123
@@ -136,6 +138,7 @@ function validatePropertyKey(name) {
138 }
139 ownerHasPropertyWarning[currentName] = true;
140
141 + monitorCodeUse('react_numeric_key_warning');
142 console.warn(
143 'Child objects should have non-numeric keys so ordering is preserved. ' +
144 'Check the render method of ' + currentName + '. ' +
src/core/ReactCompositeComponent.js
+14 -6
@@ -33,8 +33,10 @@ var invariant = require('invariant');
33 var keyMirror = require('keyMirror');
34 var merge = require('merge');
35 var mixInto = require('mixInto');
36 +var monitorCodeUse = require('monitorCodeUse');
37 var objMap = require('objMap');
38 var shouldUpdateReactComponent = require('shouldUpdateReactComponent');
39 +var warning = require('warning');
40
41 /**
42 * Policies that describe methods in `ReactCompositeComponentInterface`.
@@ -621,6 +623,7 @@ if (__DEV__) {
623 var context = owner ? ' in ' + ownerName + '.' : ' at the top level.';
624 var staticMethodExample = '<' + name + ' />.type.' + key + '(...)';
625
626 + monitorCodeUse('react_descriptor_property_access', { component: name });
627 console.warn(
628 'Invalid access to component property "' + key + '" on ' + name +
629 context + ' See http://fb.me/react-warning-descriptors .' +
@@ -904,12 +907,11 @@ var ReactCompositeComponentMixin = {
907 'setState(...): takes an object of state variables to update.'
908 );
909 if (__DEV__){
907 - if (partialState == null) {
908 - console.warn(
909 - 'setState(...): You passed an undefined or null state object; ' +
910 - 'instead, use forceUpdate().'
911 - );
912 - }
910 + warning(
911 + partialState != null,
912 + 'setState(...): You passed an undefined or null state object; ' +
913 + 'instead, use forceUpdate().'
914 + );
915 }
916 // Merge with `_pendingState` if it exists, otherwise with existing state.
917 this.replaceState(
@@ -1332,11 +1334,13 @@ var ReactCompositeComponentMixin = {
1334 // ignore the value of "this" that the user is trying to use, so
1335 // let's warn.
1336 if (newThis !== component && newThis !== null) {
1337 + monitorCodeUse('react_bind_warning', { component: componentName });
1338 console.warn(
1339 'bind(): React component methods may only be bound to the ' +
1340 'component instance. See ' + componentName
1341 );
1342 } else if (!args.length) {
1343 + monitorCodeUse('react_bind_warning', { component: componentName });
1344 console.warn(
1345 'bind(): You are binding a component method to the component. ' +
1346 'React does this for you automatically in a high-performance ' +
@@ -1421,6 +1425,10 @@ var ReactCompositeComponent = {
1425
1426 if (__DEV__) {
1427 if (Constructor.prototype.componentShouldUpdate) {
1428 + monitorCodeUse(
1429 + 'react_component_should_update_warning',
1430 + { component: spec.displayName }
1431 + );
1432 console.warn(
1433 (spec.displayName || 'A component') + ' has a method called ' +
1434 'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' +
src/event/EventPluginHub.js
+2
@@ -26,6 +26,7 @@ var accumulate = require('accumulate');
26 var forEachAccumulated = require('forEachAccumulated');
27 var invariant = require('invariant');
28 var isEventSupported = require('isEventSupported');
29 +var monitorCodeUse = require('monitorCodeUse');
30
31 /**
32 * Internal store for event listeners
@@ -168,6 +169,7 @@ var EventPluginHub = {
169 // bubble.
170 if (registrationName === 'onScroll' &&
171 !isEventSupported('scroll', true)) {
172 + monitorCodeUse('react_no_scroll_event');
173 console.warn('This browser doesn\'t support the `onScroll` event');
174 }
175 }
src/utils/cloneWithProps.js
+7 -7
@@ -22,6 +22,7 @@
22 var ReactPropTransferer = require('ReactPropTransferer');
23
24 var keyOf = require('keyOf');
25 +var warning = require('warning');
26
27 var CHILDREN_PROP = keyOf({children: null});
28
@@ -36,13 +37,12 @@ var CHILDREN_PROP = keyOf({children: null});
37 */
38 function cloneWithProps(child, props) {
39 if (__DEV__) {
39 - if (child.props.ref) {
40 - console.warn(
41 - 'You are calling cloneWithProps() on a child with a ref. This is ' +
42 - 'dangerous because you\'re creating a new child which will not be ' +
43 - 'added as a ref to its parent.'
44 - );
45 - }
40 + warning(
41 + !child.props.ref,
42 + 'You are calling cloneWithProps() on a child with a ref. This is ' +
43 + 'dangerous because you\'re creating a new child which will not be ' +
44 + 'added as a ref to its parent.'
45 + );
46 }
47
48 var newProps = ReactPropTransferer.mergeProps(props, child.props);