@samitouri / QOS-React-2 / commits / 7f205e9c1b

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 });