From 8b23a7e699972bf837decf3ea402ecc1b864f76e Mon Sep 17 00:00:00 2001 From: Cheng Lou Date: Sun, 27 Apr 2014 13:15:00 -0700 Subject: [PATCH] Warn instead of throw for nested render calls --- src/browser/ui/ReactMount.js | 5 +++-- src/core/ReactUpdates.js | 3 ++- src/core/__tests__/ReactCompositeComponent-test.js | 9 +++++---- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/browser/ui/ReactMount.js b/src/browser/ui/ReactMount.js index 7a0ce89e4a..e898b58994 100644 --- a/src/browser/ui/ReactMount.js +++ b/src/browser/ui/ReactMount.js @@ -29,6 +29,7 @@ var getReactRootElementInContainer = require('getReactRootElementInContainer'); var instantiateReactComponent = require('instantiateReactComponent'); var invariant = require('invariant'); var shouldUpdateReactComponent = require('shouldUpdateReactComponent'); +var warning = require('warning'); var SEPARATOR = ReactInstanceHandles.SEPARATOR; @@ -301,7 +302,7 @@ var ReactMount = { // Various parts of our code (such as ReactCompositeComponent's // _renderValidatedComponent) assume that calls to render aren't nested; // verify that that's the case. - invariant( + warning( ReactCurrentOwner.current == null, '_renderNewRootComponent(): Render methods should be a pure function ' + 'of props and state; triggering nested component updates from ' + @@ -440,7 +441,7 @@ var ReactMount = { // _renderValidatedComponent) assume that calls to render aren't nested; // verify that that's the case. (Strictly speaking, unmounting won't cause a // render but we still don't expect to be in a render call here.) - invariant( + warning( ReactCurrentOwner.current == null, 'unmountComponentAtNode(): Render methods should be a pure function of ' + 'props and state; triggering nested component updates from render is ' + diff --git a/src/core/ReactUpdates.js b/src/core/ReactUpdates.js index 1eb6a07077..56da4aef14 100644 --- a/src/core/ReactUpdates.js +++ b/src/core/ReactUpdates.js @@ -22,6 +22,7 @@ var ReactCurrentOwner = require('ReactCurrentOwner'); var ReactPerf = require('ReactPerf'); var invariant = require('invariant'); +var warning = require('warning'); var dirtyComponents = []; @@ -109,7 +110,7 @@ function enqueueUpdate(component, callback) { // verify that that's the case. (This is called by each top-level update // function, like setProps, setState, forceUpdate, etc.; creation and // destruction of top-level components is guarded in ReactMount.) - invariant( + warning( ReactCurrentOwner.current == null, 'enqueueUpdate(): Render methods should be a pure function of props ' + 'and state; triggering nested component updates from render is not ' + diff --git a/src/core/__tests__/ReactCompositeComponent-test.js b/src/core/__tests__/ReactCompositeComponent-test.js index abb43e4565..e3a9d2af52 100644 --- a/src/core/__tests__/ReactCompositeComponent-test.js +++ b/src/core/__tests__/ReactCompositeComponent-test.js @@ -1346,6 +1346,7 @@ describe('ReactCompositeComponent', function() { }); it('should disallow nested render calls', function() { + spyOn(console, 'warn'); var Inner = React.createClass({ render: function() { return
; @@ -1358,10 +1359,10 @@ describe('ReactCompositeComponent', function() { } }); - expect(() => { - ReactTestUtils.renderIntoDocument(); - }).toThrow( - 'Invariant Violation: _renderNewRootComponent(): Render methods should ' + + ReactTestUtils.renderIntoDocument(); + expect(console.warn.argsForCall.length).toBe(1); + expect(console.warn.argsForCall[0][0]).toBe( + 'Warning: _renderNewRootComponent(): Render methods should ' + 'be a pure function of props and state; triggering nested component ' + 'updates from render is not allowed. If necessary, trigger nested ' + 'updates in componentDidUpdate.'