Don't skip reconcilation if context differs
Jim committed
Jul 10, 2015 at 17:50 UTC
9baaeec21d05c717e1fa02f72de458c1df257f8a
3 files changed
+73
-6
src/renderers/shared/reconciler/ReactReconciler.js
+2
-2
@@ -66,8 +66,8 @@ var ReactReconciler = {
66
) {
67
var prevElement = internalInstance._currentElement;
68
if (nextElement === prevElement &&
69
- nextElement._owner != null
70
- // TODO: Shouldn't we need to do this: `&& context === internalInstance._context`
69
+ nextElement._owner != null &&
70
+ context === internalInstance._context
71
) {
72
// Since elements are immutable after the owner is rendered,
73
// we can do a cheap identity compare here to determine if this is a
src/renderers/shared/reconciler/__tests__/ReactCompositeComponent-test.js
+62
@@ -667,6 +667,68 @@ describe('ReactCompositeComponent', function() {
667
reactComponentExpect(childInstance).scalarContextEqual({foo: 'bar', flag: true});
668
});
669
670
+ it('should pass context when re-rendered for static child within a composite component', function() {
671
+ var Parent = React.createClass({
672
+ childContextTypes: {
673
+ flag: ReactPropTypes.bool,
674
+ },
675
+
676
+ getChildContext() {
677
+ return {
678
+ flag: this.state.flag,
679
+ };
680
+ },
681
+
682
+ getInitialState: function() {
683
+ return {
684
+ flag: true,
685
+ };
686
+ },
687
+
688
+ render() {
689
+ return <div>{this.props.children}</div>;
690
+ },
691
+
692
+ });
693
+
694
+ var Child = React.createClass({
695
+ contextTypes: {
696
+ flag: ReactPropTypes.bool,
697
+ },
698
+
699
+ render: function() {
700
+ return <div />;
701
+ },
702
+ });
703
+
704
+ var Wrapper = React.createClass({
705
+ render() {
706
+ return (
707
+ <Parent ref="parent">
708
+ <Child ref="child" />
709
+ </Parent>
710
+ );
711
+ },
712
+ });
713
+
714
+
715
+ var wrapper = ReactTestUtils.renderIntoDocument(
716
+ <Wrapper />
717
+ );
718
+
719
+ expect(wrapper.refs.parent.state.flag).toEqual(true);
720
+ reactComponentExpect(wrapper.refs.child).scalarContextEqual({flag: true});
721
+
722
+ // We update <Parent /> while <Child /> is still a static prop relative to this update
723
+ wrapper.refs.parent.setState({flag: false});
724
+
725
+ expect(console.error.argsForCall.length).toBe(0);
726
+
727
+ expect(wrapper.refs.parent.state.flag).toEqual(false);
728
+ reactComponentExpect(wrapper.refs.child).scalarContextEqual({flag: false});
729
+
730
+ });
731
+
732
it('should pass context transitively', function() {
733
var childInstance = null;
734
var grandchildInstance = null;
src/renderers/shared/reconciler/__tests__/ReactUpdates-test.js
+9
-4
@@ -433,10 +433,15 @@ describe('ReactUpdates', function() {
433
root = ReactTestUtils.renderIntoDocument(root);
434
435
function expectUpdates(desiredWillUpdates, desiredDidUpdates) {
436
- expect(willUpdates).toEqual(desiredWillUpdates);
437
- expect(didUpdates).toEqual(desiredDidUpdates);
438
- willUpdates.length = 0;
439
- didUpdates.length = 0;
436
+ var i;
437
+ for (i = 0; i < desiredWillUpdates; i++) {
438
+ expect(willUpdates).toContain(desiredWillUpdates[i]);
439
+ }
440
+ for (i = 0; i < desiredDidUpdates; i++) {
441
+ expect(didUpdates).toContain(desiredDidUpdates[i]);
442
+ }
443
+ willUpdates = [];
444
+ didUpdates = [];
445
}
446
447
function triggerUpdate(c) {