Set the owner during traverseAllChildren
This is basically just adding some context to the warning in ReactFragment so that we can more easily find the callers.
Sebastian Markbage committed
Aug 5, 2015 at 21:04 UTC
cd1ab32d2f0f814c4cdf7293d81566dfab1e740d
2 files changed
+60
-2
src/addons/__tests__/ReactFragment-test.js
+21
@@ -58,6 +58,27 @@ describe('ReactFragment', function() {
58
);
59
});
60
61
+ it('should warn if a plain object even if it is in an owner', function() {
62
+ spyOn(console, 'error');
63
+ class Foo {
64
+ render() {
65
+ var children = {
66
+ a: <span />,
67
+ b: <span />,
68
+ c: <span />,
69
+ };
70
+ return <div>{[children]}</div>;
71
+ }
72
+ }
73
+ expect(console.error.calls.length).toBe(0);
74
+ var container = document.createElement('div');
75
+ React.render(<Foo />, container);
76
+ expect(console.error.calls.length).toBe(1);
77
+ expect(console.error.calls[0].args[0]).toContain(
78
+ 'Any use of a keyed object'
79
+ );
80
+ });
81
+
82
it('should warn if accessing any property on a fragment', function() {
83
spyOn(console, 'error');
84
var children = {
src/renderers/shared/reconciler/ReactMultiChild.js
+39
-2
@@ -15,6 +15,7 @@
15
var ReactComponentEnvironment = require('ReactComponentEnvironment');
16
var ReactMultiChildUpdateTypes = require('ReactMultiChildUpdateTypes');
17
18
+var ReactCurrentOwner = require('ReactCurrentOwner');
19
var ReactReconciler = require('ReactReconciler');
20
var ReactChildReconciler = require('ReactChildReconciler');
21
@@ -189,6 +190,42 @@ var ReactMultiChild = {
190
*/
191
Mixin: {
192
193
+ _reconcilerInstantiateChildren: function(nestedChildren, transaction, context) {
194
+ if (__DEV__) {
195
+ if (this._currentElement) {
196
+ try {
197
+ ReactCurrentOwner.current = this._currentElement._owner;
198
+ return ReactChildReconciler.instantiateChildren(
199
+ nestedChildren, transaction, context
200
+ );
201
+ } finally {
202
+ ReactCurrentOwner.current = null;
203
+ }
204
+ }
205
+ }
206
+ return ReactChildReconciler.instantiateChildren(
207
+ nestedChildren, transaction, context
208
+ );
209
+ },
210
+
211
+ _reconcilerUpdateChildren: function(prevChildren, nextNestedChildrenElements, transaction, context) {
212
+ if (__DEV__) {
213
+ if (this._currentElement) {
214
+ try {
215
+ ReactCurrentOwner.current = this._currentElement._owner;
216
+ return ReactChildReconciler.updateChildren(
217
+ prevChildren, nextNestedChildrenElements, transaction, context
218
+ );
219
+ } finally {
220
+ ReactCurrentOwner.current = null;
221
+ }
222
+ }
223
+ }
224
+ return ReactChildReconciler.updateChildren(
225
+ prevChildren, nextNestedChildrenElements, transaction, context
226
+ );
227
+ },
228
+
229
/**
230
* Generates a "mount image" for each of the supplied children. In the case
231
* of `ReactDOMComponent`, a mount image is a string of markup.
@@ -198,7 +235,7 @@ var ReactMultiChild = {
235
* @internal
236
*/
237
mountChildren: function(nestedChildren, transaction, context) {
201
- var children = ReactChildReconciler.instantiateChildren(
238
+ var children = this._reconcilerInstantiateChildren(
239
nestedChildren, transaction, context
240
);
241
this._renderedChildren = children;
@@ -326,7 +363,7 @@ var ReactMultiChild = {
363
*/
364
_updateChildren: function(nextNestedChildrenElements, transaction, context) {
365
var prevChildren = this._renderedChildren;
329
- var nextChildren = ReactChildReconciler.updateChildren(
366
+ var nextChildren = this._reconcilerUpdateChildren(
367
prevChildren, nextNestedChildrenElements, transaction, context
368
);
369
this._renderedChildren = nextChildren;