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.
This commit is contained in:
Sebastian Markbage
2015-06-18 13:35:39 -07:00
parent 40b7c19a89
commit e737acb472
2 changed files with 9 additions and 12 deletions
@@ -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) {
@@ -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(<Component prop={123} />, container);