diff --git a/src/addons/__tests__/ReactFragment-test.js b/src/addons/__tests__/ReactFragment-test.js index bb7cb7cc35..d3ef590276 100644 --- a/src/addons/__tests__/ReactFragment-test.js +++ b/src/addons/__tests__/ReactFragment-test.js @@ -58,6 +58,27 @@ describe('ReactFragment', function() { ); }); + it('should warn if a plain object even if it is in an owner', function() { + spyOn(console, 'error'); + class Foo { + render() { + var children = { + a: , + b: , + c: , + }; + return
{[children]}
; + } + } + expect(console.error.calls.length).toBe(0); + var container = document.createElement('div'); + React.render(, container); + expect(console.error.calls.length).toBe(1); + expect(console.error.calls[0].args[0]).toContain( + 'Any use of a keyed object' + ); + }); + it('should warn if accessing any property on a fragment', function() { spyOn(console, 'error'); var children = { diff --git a/src/renderers/shared/reconciler/ReactMultiChild.js b/src/renderers/shared/reconciler/ReactMultiChild.js index 079fa86f7e..10e22f9b0c 100644 --- a/src/renderers/shared/reconciler/ReactMultiChild.js +++ b/src/renderers/shared/reconciler/ReactMultiChild.js @@ -15,6 +15,7 @@ var ReactComponentEnvironment = require('ReactComponentEnvironment'); var ReactMultiChildUpdateTypes = require('ReactMultiChildUpdateTypes'); +var ReactCurrentOwner = require('ReactCurrentOwner'); var ReactReconciler = require('ReactReconciler'); var ReactChildReconciler = require('ReactChildReconciler'); @@ -189,6 +190,42 @@ var ReactMultiChild = { */ Mixin: { + _reconcilerInstantiateChildren: function(nestedChildren, transaction, context) { + if (__DEV__) { + if (this._currentElement) { + try { + ReactCurrentOwner.current = this._currentElement._owner; + return ReactChildReconciler.instantiateChildren( + nestedChildren, transaction, context + ); + } finally { + ReactCurrentOwner.current = null; + } + } + } + return ReactChildReconciler.instantiateChildren( + nestedChildren, transaction, context + ); + }, + + _reconcilerUpdateChildren: function(prevChildren, nextNestedChildrenElements, transaction, context) { + if (__DEV__) { + if (this._currentElement) { + try { + ReactCurrentOwner.current = this._currentElement._owner; + return ReactChildReconciler.updateChildren( + prevChildren, nextNestedChildrenElements, transaction, context + ); + } finally { + ReactCurrentOwner.current = null; + } + } + } + return ReactChildReconciler.updateChildren( + prevChildren, nextNestedChildrenElements, transaction, context + ); + }, + /** * Generates a "mount image" for each of the supplied children. In the case * of `ReactDOMComponent`, a mount image is a string of markup. @@ -198,7 +235,7 @@ var ReactMultiChild = { * @internal */ mountChildren: function(nestedChildren, transaction, context) { - var children = ReactChildReconciler.instantiateChildren( + var children = this._reconcilerInstantiateChildren( nestedChildren, transaction, context ); this._renderedChildren = children; @@ -326,7 +363,7 @@ var ReactMultiChild = { */ _updateChildren: function(nextNestedChildrenElements, transaction, context) { var prevChildren = this._renderedChildren; - var nextChildren = ReactChildReconciler.updateChildren( + var nextChildren = this._reconcilerUpdateChildren( prevChildren, nextNestedChildrenElements, transaction, context ); this._renderedChildren = nextChildren;