@samitouri / QOS-React-2 / commits / 00f2a053f0

Warn for numeric object properties

Numeric keys will be ordered sequentially in Chrome/Firefox. Warn the user if such keys are set on a child.

Josh Duck committed Jan 29, 2014 at 12:50 UTC 00f2a053f0fd4a3923eafe7b4a27450da3bdbe9c
1 file changed +39 -7
src/core/ReactComponent.js
+39 -7
@@ -43,11 +43,13 @@ var ComponentLifeCycle = keyMirror({
43 });
44
45 /**
46 - * Warn if there's no key explicitly set on dynamic arrays of children.
47 - * This allows us to keep track of children between updates.
46 + * Warn if there's no key explicitly set on dynamic arrays of children or
47 + * object keys are not valid. This allows us to keep track of children between
48 + * updates.
49 */
50
50 -var ownerHasWarned = {};
51 +var ownerHasExplicitKeyWarning = {};
52 +var ownerHasPropertyWarning = {};
53
54 /**
55 * Warn if the component doesn't have an explicit key assigned to it.
@@ -71,10 +73,10 @@ function validateExplicitKey(component) {
73
74 // Name of the component whose render method tried to pass children.
75 var currentName = ReactCurrentOwner.current.constructor.displayName;
74 - if (ownerHasWarned.hasOwnProperty(currentName)) {
76 + if (ownerHasExplicitKeyWarning.hasOwnProperty(currentName)) {
77 return;
78 }
77 - ownerHasWarned[currentName] = true;
79 + ownerHasExplicitKeyWarning[currentName] = true;
80
81 var message = 'Each child in an array should have a unique "key" prop. ' +
82 'Check the render method of ' + currentName + '.';
@@ -95,8 +97,34 @@ function validateExplicitKey(component) {
97 }
98
99 /**
98 - * Ensure that every component either is passed in a static location or, if
99 - * if it's passed in an array, has an explicit key property defined.
100 + * Warn if the key is being defined as an object property but has an incorrect
101 + * value.
102 + *
103 + * @internal
104 + * @param {string} name Property name of the key.
105 + * @param {ReactComponent} component Component that requires a key.
106 + */
107 +function validatePropertyKey(name) {
108 + if (!isNaN(Number(name))) {
109 + // Name of the component whose render method tried to pass children.
110 + var currentName = ReactCurrentOwner.current.constructor.displayName;
111 + if (ownerHasPropertyWarning.hasOwnProperty(currentName)) {
112 + return;
113 + }
114 + ownerHasPropertyWarning[currentName] = true;
115 +
116 + console.warn(
117 + 'Child objects should have non-numeric keys so ordering is preserved. ' +
118 + 'Check the render method of ' + currentName + '. ' +
119 + 'See http://fb.me/react-warning-keys for more information.'
120 + );
121 + }
122 +}
123 +
124 +/**
125 + * Ensure that every component either is passed in a static location, in an
126 + * array with an explicit keys property defined, or in an object literal
127 + * with valid key property.
128 *
129 * @internal
130 * @param {*} component Statically passed child of any type.
@@ -113,6 +141,10 @@ function validateChildKeys(component) {
141 } else if (ReactComponent.isValidComponent(component)) {
142 // This component was passed in a valid location.
143 component.__keyValidated__ = true;
144 + } else if (component && typeof component === 'object') {
145 + for (var name in component) {
146 + validatePropertyKey(name, component);
147 + }
148 }
149 }
150