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.
Sebastian Markbage committed
Jun 18, 2015 at 12:59 UTC
e737acb47223a3b1e77f54ddcc4cbbc38ec68b06
2 files changed
+9
-12
src/renderers/shared/reconciler/ReactUpdateQueue.js
+1
-7
@@ -22,13 +22,7 @@ var invariant = require('invariant');
22
var warning = require('warning');
23
24
function enqueueUpdate(internalInstance) {
25
- if (internalInstance !== ReactLifeCycle.currentlyMountingInstance) {
26
- // If we're in a componentWillMount handler, don't enqueue a rerender
27
- // because ReactUpdates assumes we're in a browser context (which is
28
- // wrong for server rendering) and we're about to do a render anyway.
29
- // See bug in #1740.
30
- ReactUpdates.enqueueUpdate(internalInstance);
31
- }
25
+ ReactUpdates.enqueueUpdate(internalInstance);
26
}
27
28
function getInternalInstanceReadyForUpdate(publicInstance, callerName) {
src/renderers/shared/reconciler/__tests__/ReactCompositeComponent-test.js
+8
-5
@@ -351,12 +351,14 @@ describe('ReactCompositeComponent', function() {
351
var container = document.createElement('div');
352
353
var renderedState = -1;
354
+ var renderPasses = 0;
355
356
var Component = React.createClass({
357
getInitialState: function() {
358
return {value: 0};
359
},
360
render: function() {
361
+ renderPasses++;
362
renderedState = this.state.value;
363
if (this.state.value === 0) {
364
this.setState({ value: 1 });
@@ -376,11 +378,12 @@ describe('ReactCompositeComponent', function() {
378
'function of props and state.'
379
);
380
379
- // The setState call is queued but the result isn't immediately available
380
- // during this pass. It is queued up but not flushed. The behavior is more
381
- // or less undefined.
382
- expect(renderedState).toBe(0);
383
- expect(instance.state.value).toBe(0);
381
+ // The setState call is queued and then executed as a second pass. This
382
+ // behavior is undefined though so we're free to change it to suit the
383
+ // implementation details.
384
+ expect(renderPasses).toBe(2);
385
+ expect(renderedState).toBe(1);
386
+ expect(instance.state.value).toBe(1);
387
388
// Forcing a rerender anywhere will cause the update to happen.
389
var instance2 = React.render(<Component prop={123} />, container);