From 1922db1711b24028b3c794f212d0452eb4e95b09 Mon Sep 17 00:00:00 2001 From: Ben Alpert Date: Wed, 23 Sep 2015 11:25:25 -0700 Subject: [PATCH] Improve traverseAllChildren object error message Fixes #4840. --- src/addons/__tests__/ReactFragment-test.js | 9 +++---- .../__tests__/traverseAllChildren-test.js | 24 +++++++++++++++++++ src/shared/utils/traverseAllChildren.js | 12 ++++++---- 3 files changed, 36 insertions(+), 9 deletions(-) diff --git a/src/addons/__tests__/ReactFragment-test.js b/src/addons/__tests__/ReactFragment-test.js index 741942b704..237e10692d 100644 --- a/src/addons/__tests__/ReactFragment-test.js +++ b/src/addons/__tests__/ReactFragment-test.js @@ -32,10 +32,10 @@ describe('ReactFragment', function() { var element =
{[children]}
; var container = document.createElement('div'); expect(() => ReactDOM.render(element, container)).toThrow( - 'Invariant Violation: Objects are not valid as a React child (found ' + + 'Invariant Violation: Objects are not valid as a React child (found: ' + 'object with keys {x, y, z}). If you meant to render a collection of ' + 'children, use an array instead or wrap the object using ' + - 'React.addons.createFragment(object).' + 'createFragment(object) from the React add-ons.' ); }); @@ -52,10 +52,11 @@ describe('ReactFragment', function() { } var container = document.createElement('div'); expect(() => ReactDOM.render(, container)).toThrow( - 'Invariant Violation: Objects are not valid as a React child (found ' + + 'Invariant Violation: Objects are not valid as a React child (found: ' + 'object with keys {a, b, c}). If you meant to render a collection of ' + 'children, use an array instead or wrap the object using ' + - 'React.addons.createFragment(object). Check the render method of `Foo`.' + 'createFragment(object) from the React add-ons. Check the render ' + + 'method of `Foo`.' ); }); diff --git a/src/shared/utils/__tests__/traverseAllChildren-test.js b/src/shared/utils/__tests__/traverseAllChildren-test.js index 5c95ec8828..96666915fd 100644 --- a/src/shared/utils/__tests__/traverseAllChildren-test.js +++ b/src/shared/utils/__tests__/traverseAllChildren-test.js @@ -476,4 +476,28 @@ describe('traverseAllChildren', function() { } }); + it('should throw on object', function() { + expect(function() { + traverseAllChildren({a: 1, b: 2}, function() {}, null); + }).toThrow( + 'Invariant Violation: Objects are not valid as a React child (found: ' + + 'object with keys {a, b}). If you meant to render a collection of ' + + 'children, use an array instead or wrap the object using ' + + 'createFragment(object) from the React add-ons.' + ); + }); + + it('should throw on regex', function() { + // Really, we care about dates (#4840) but those have nondeterministic + // serialization (timezones) so let's test a regex instead: + expect(function() { + traverseAllChildren(/abc/, function() {}, null); + }).toThrow( + 'Invariant Violation: Objects are not valid as a React child (found: ' + + '/abc/). If you meant to render a collection of children, use an array ' + + 'instead or wrap the object using createFragment(object) from the ' + + 'React add-ons.' + ); + }); + }); diff --git a/src/shared/utils/traverseAllChildren.js b/src/shared/utils/traverseAllChildren.js index 011f7a094a..6733735867 100644 --- a/src/shared/utils/traverseAllChildren.js +++ b/src/shared/utils/traverseAllChildren.js @@ -188,13 +188,15 @@ function traverseAllChildrenImpl( } } } + var childrenString = String(children); invariant( false, - 'Objects are not valid as a React child (found object with keys ' + - '{%s}). If you meant to render a collection of children, use an ' + - 'array instead or wrap the object using ' + - 'React.addons.createFragment(object).%s', - Object.keys(children).join(', '), + 'Objects are not valid as a React child (found: %s). If you meant to ' + + 'render a collection of children, use an array instead or wrap the ' + + 'object using createFragment(object) from the React add-ons.%s', + childrenString === '[object Object]' ? + 'object with keys {' + Object.keys(children).join(', ') + '}' : + childrenString, addendum ); }