Make sure top-level callback has correct context
Closes #5125 -- incorporates essentially the same fix with a much simpler test case. Thanks @yiminghe for reporting!
Ben Alpert committed
Oct 21, 2015 at 15:01 UTC
7f205e9c1ba30d4e30cd5a1a268a90ac07521947
2 files changed
+48
-3
src/renderers/dom/client/ReactMount.js
+8
-3
@@ -610,12 +610,17 @@ var ReactMount = {
610
var prevWrappedElement = prevComponent._currentElement;
611
var prevElement = prevWrappedElement.props;
612
if (shouldUpdateReactComponent(prevElement, nextElement)) {
613
- return ReactMount._updateRootComponent(
613
+ var publicInst = prevComponent._renderedComponent.getPublicInstance();
614
+ var updatedCallback = callback && function() {
615
+ callback.call(publicInst);
616
+ };
617
+ ReactMount._updateRootComponent(
618
prevComponent,
619
nextWrappedElement,
620
container,
617
- callback
618
- )._renderedComponent.getPublicInstance();
621
+ updatedCallback
622
+ );
623
+ return publicInst;
624
} else {
625
ReactMount.unmountComponentAtNode(container);
626
}
src/renderers/dom/client/__tests__/ReactMount-test.js
+40
@@ -299,4 +299,44 @@ describe('ReactMount', function() {
299
ReactDOM.render(<Component step={1} />, container);
300
ReactMount.getID(container.querySelector('a'));
301
});
302
+
303
+ it('passes the correct callback context', function() {
304
+ var container = document.createElement('div');
305
+ var calls = 0;
306
+
307
+ ReactDOM.render(<div />, container, function() {
308
+ expect(this.nodeName).toBe('DIV');
309
+ calls++;
310
+ });
311
+
312
+ // Update, no type change
313
+ ReactDOM.render(<div />, container, function() {
314
+ expect(this.nodeName).toBe('DIV');
315
+ calls++;
316
+ });
317
+
318
+ // Update, type change
319
+ ReactDOM.render(<span />, container, function() {
320
+ expect(this.nodeName).toBe('SPAN');
321
+ calls++;
322
+ });
323
+
324
+ // Batched update, no type change
325
+ ReactDOM.unstable_batchedUpdates(function() {
326
+ ReactDOM.render(<span />, container, function() {
327
+ expect(this.nodeName).toBe('SPAN');
328
+ calls++;
329
+ });
330
+ });
331
+
332
+ // Batched update, type change
333
+ ReactDOM.unstable_batchedUpdates(function() {
334
+ ReactDOM.render(<article />, container, function() {
335
+ expect(this.nodeName).toBe('ARTICLE');
336
+ calls++;
337
+ });
338
+ });
339
+
340
+ expect(calls).toBe(5);
341
+ });
342
});