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