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.
This commit is contained in:
Sebastian Markbage
2015-08-05 21:04:52 -07:00
parent e64fc51984
commit cd1ab32d2f
2 changed files with 60 additions and 2 deletions
@@ -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: <span />,
b: <span />,
c: <span />,
};
return <div>{[children]}</div>;
}
}
expect(console.error.calls.length).toBe(0);
var container = document.createElement('div');
React.render(<Foo />, 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 = {
@@ -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;