diff --git a/scripts/fiber/tests-failing.txt b/scripts/fiber/tests-failing.txt
index 8d705c30e8..254abf87b2 100644
--- a/scripts/fiber/tests-failing.txt
+++ b/scripts/fiber/tests-failing.txt
@@ -82,9 +82,6 @@ src/renderers/shared/shared/__tests__/ReactCompositeComponent-test.js
* should warn about `setState` in getChildContext
* should update refs if shouldComponentUpdate gives false
-src/renderers/shared/shared/__tests__/ReactCompositeComponentNestedState-test.js
-* should provide up to date values for props
-
src/renderers/shared/shared/__tests__/ReactCompositeComponentState-test.js
* should update state when called from child cWRP
diff --git a/scripts/fiber/tests-passing.txt b/scripts/fiber/tests-passing.txt
index 002f3c042f..2c127f082d 100644
--- a/scripts/fiber/tests-passing.txt
+++ b/scripts/fiber/tests-passing.txt
@@ -505,6 +505,7 @@ src/renderers/dom/fiber/__tests__/ReactDOMFiber-test.js
* should render strings as children
* should render numbers as children
* should be called a callback argument
+* should call a callback argument when the same element is re-rendered
* should render a component returning strings directly from render
* should render a component returning numbers directly from render
* finds the DOM Text node of a string child
@@ -1323,6 +1324,9 @@ src/renderers/shared/shared/__tests__/ReactCompositeComponentDOMMinimalism-test.
* should not render extra nodes for non-interpolated text
* should not render extra nodes for non-interpolated text
+src/renderers/shared/shared/__tests__/ReactCompositeComponentNestedState-test.js
+* should provide up to date values for props
+
src/renderers/shared/shared/__tests__/ReactCompositeComponentState-test.js
* should support setting state
* should call componentDidUpdate of children first
diff --git a/src/renderers/dom/fiber/__tests__/ReactDOMFiber-test.js b/src/renderers/dom/fiber/__tests__/ReactDOMFiber-test.js
index 6dd3146541..990ad069d1 100644
--- a/src/renderers/dom/fiber/__tests__/ReactDOMFiber-test.js
+++ b/src/renderers/dom/fiber/__tests__/ReactDOMFiber-test.js
@@ -64,6 +64,35 @@ describe('ReactDOMFiber', () => {
expect(called).toEqual(true);
});
+ it('should call a callback argument when the same element is re-rendered', () => {
+ class Foo extends React.Component {
+ render() {
+ return
Foo
;
+ }
+ }
+ const element = ;
+
+ // mounting phase
+ let called = false;
+ ReactDOM.render(
+ element,
+ container,
+ () => called = true
+ );
+ expect(called).toEqual(true);
+
+ // updating phase
+ called = false;
+ ReactDOM.unstable_batchedUpdates(() => {
+ ReactDOM.render(
+ element,
+ container,
+ () => called = true
+ );
+ });
+ expect(called).toEqual(true);
+ });
+
if (ReactDOMFeatureFlags.useFiber) {
it('should render a component returning strings directly from render', () => {
const Text = ({value}) => value;
diff --git a/src/renderers/shared/shared/__tests__/ReactCompositeComponentNestedState-test.js b/src/renderers/shared/shared/__tests__/ReactCompositeComponentNestedState-test.js
index b44bac3139..1c95f72293 100644
--- a/src/renderers/shared/shared/__tests__/ReactCompositeComponentNestedState-test.js
+++ b/src/renderers/shared/shared/__tests__/ReactCompositeComponentNestedState-test.js
@@ -111,8 +111,8 @@ describe('ReactCompositeComponentNestedState-state', () => {
['setState-this', 'dark blue', 'blue'],
['setState-args', 'dark blue', 'green'],
['render', 'light green', 'green'],
- ['parent-after-setState', 'green'],
['after-setState', 'light green', 'green'],
+ ['parent-after-setState', 'green'],
]);
});
});
diff --git a/src/renderers/shared/stack/reconciler/ReactCompositeComponent.js b/src/renderers/shared/stack/reconciler/ReactCompositeComponent.js
index 2a15d71383..0064b18d3d 100644
--- a/src/renderers/shared/stack/reconciler/ReactCompositeComponent.js
+++ b/src/renderers/shared/stack/reconciler/ReactCompositeComponent.js
@@ -780,6 +780,16 @@ var ReactCompositeComponent = {
this._context
);
} else {
+ var callbacks = this._pendingCallbacks;
+ this._pendingCallbacks = null;
+ if (callbacks) {
+ for (var j = 0; j < callbacks.length; j++) {
+ transaction.getReactMountReady().enqueue(
+ callbacks[j],
+ this.getPublicInstance()
+ );
+ }
+ }
this._updateBatchNumber = null;
}
},
@@ -848,6 +858,11 @@ var ReactCompositeComponent = {
}
}
+ // If updating happens to enqueue any new updates, we shouldn't execute new
+ // callbacks until the next render happens, so stash the callbacks first.
+ var callbacks = this._pendingCallbacks;
+ this._pendingCallbacks = null;
+
var nextState = this._processPendingState(nextProps, nextContext);
var shouldUpdate = true;
@@ -901,6 +916,15 @@ var ReactCompositeComponent = {
inst.state = nextState;
inst.context = nextContext;
}
+
+ if (callbacks) {
+ for (var j = 0; j < callbacks.length; j++) {
+ transaction.getReactMountReady().enqueue(
+ callbacks[j],
+ this.getPublicInstance()
+ );
+ }
+ }
},
_processPendingState: function(props, context) {
diff --git a/src/renderers/shared/stack/reconciler/ReactUpdates.js b/src/renderers/shared/stack/reconciler/ReactUpdates.js
index 2e44516430..8971a7c357 100644
--- a/src/renderers/shared/stack/reconciler/ReactUpdates.js
+++ b/src/renderers/shared/stack/reconciler/ReactUpdates.js
@@ -135,12 +135,6 @@ function runBatchedUpdates(transaction) {
// that performUpdateIfNecessary is a noop.
var component = dirtyComponents[i];
- // If performUpdateIfNecessary happens to enqueue any new updates, we
- // shouldn't execute the callbacks until the next render happens, so
- // stash the callbacks first
- var callbacks = component._pendingCallbacks;
- component._pendingCallbacks = null;
-
var markerName;
if (ReactFeatureFlags.logTopLevelRenders) {
var namedComponent = component;
@@ -161,15 +155,6 @@ function runBatchedUpdates(transaction) {
if (markerName) {
console.timeEnd(markerName);
}
-
- if (callbacks) {
- for (var j = 0; j < callbacks.length; j++) {
- transaction.reconcileTransaction.getReactMountReady().enqueue(
- callbacks[j],
- component.getPublicInstance()
- );
- }
- }
}
}