From e737acb47223a3b1e77f54ddcc4cbbc38ec68b06 Mon Sep 17 00:00:00 2001 From: Sebastian Markbage Date: Thu, 18 Jun 2015 12:59:08 -0700 Subject: [PATCH] Let updates be enqueued during render This allows updates to be enqueued during render. setState in componentWillMount will still be collected as part of the first pass so if nothing else get added as pending, they won't trigger a second rerender. This allow us to get rid of one more stateful special case. --- src/renderers/shared/reconciler/ReactUpdateQueue.js | 8 +------- .../__tests__/ReactCompositeComponent-test.js | 13 ++++++++----- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/renderers/shared/reconciler/ReactUpdateQueue.js b/src/renderers/shared/reconciler/ReactUpdateQueue.js index 75d7a33d17..dbb81c039f 100644 --- a/src/renderers/shared/reconciler/ReactUpdateQueue.js +++ b/src/renderers/shared/reconciler/ReactUpdateQueue.js @@ -22,13 +22,7 @@ var invariant = require('invariant'); var warning = require('warning'); function enqueueUpdate(internalInstance) { - if (internalInstance !== ReactLifeCycle.currentlyMountingInstance) { - // If we're in a componentWillMount handler, don't enqueue a rerender - // because ReactUpdates assumes we're in a browser context (which is - // wrong for server rendering) and we're about to do a render anyway. - // See bug in #1740. - ReactUpdates.enqueueUpdate(internalInstance); - } + ReactUpdates.enqueueUpdate(internalInstance); } function getInternalInstanceReadyForUpdate(publicInstance, callerName) { diff --git a/src/renderers/shared/reconciler/__tests__/ReactCompositeComponent-test.js b/src/renderers/shared/reconciler/__tests__/ReactCompositeComponent-test.js index eb052aad3b..8b4c1b8963 100644 --- a/src/renderers/shared/reconciler/__tests__/ReactCompositeComponent-test.js +++ b/src/renderers/shared/reconciler/__tests__/ReactCompositeComponent-test.js @@ -351,12 +351,14 @@ describe('ReactCompositeComponent', function() { var container = document.createElement('div'); var renderedState = -1; + var renderPasses = 0; var Component = React.createClass({ getInitialState: function() { return {value: 0}; }, render: function() { + renderPasses++; renderedState = this.state.value; if (this.state.value === 0) { this.setState({ value: 1 }); @@ -376,11 +378,12 @@ describe('ReactCompositeComponent', function() { 'function of props and state.' ); - // The setState call is queued but the result isn't immediately available - // during this pass. It is queued up but not flushed. The behavior is more - // or less undefined. - expect(renderedState).toBe(0); - expect(instance.state.value).toBe(0); + // The setState call is queued and then executed as a second pass. This + // behavior is undefined though so we're free to change it to suit the + // implementation details. + expect(renderPasses).toBe(2); + expect(renderedState).toBe(1); + expect(instance.state.value).toBe(1); // Forcing a rerender anywhere will cause the update to happen. var instance2 = React.render(, container);