Warn if context values differ, related to issue #2112
Jim committed
Nov 25, 2014 at 15:43 UTC
90d75ab099be09b25842084cbb3886335e91c5a7
2 files changed
+70
-11
src/core/ReactCompositeComponent.js
+28
-10
@@ -597,16 +597,34 @@ var ReactCompositeComponentMixin = assign({},
597
_warnIfContextsDiffer: function(ownerBasedContext, parentBasedContext) {
598
var ownerKeys = Object.keys(ownerBasedContext).sort();
599
var parentKeys = Object.keys(parentBasedContext).sort();
600
- warning(
601
- ownerKeys.length === parentKeys.length &&
602
- ownerKeys.toString() === parentKeys.toString(),
603
- 'owner based context (keys: %s) does not equal parent based' +
604
- ' context (keys: %s) while mounting %s' +
605
- ' (see: http://fb.me/react-context-by-parent)',
606
- Object.keys(ownerBasedContext),
607
- Object.keys(parentBasedContext),
608
- (this._instance.constructor.displayName || 'ReactCompositeComponent')
609
- );
600
+ var displayName = this._instance.constructor.displayName || 'ReactCompositeComponent';
601
+ if (ownerKeys.length !== parentKeys.length ||
602
+ ownerKeys.toString() !== parentKeys.toString()) {
603
+ warning(
604
+ ownerKeys.length === parentKeys.length &&
605
+ ownerKeys.toString() === parentKeys.toString(),
606
+ 'owner based context (keys: %s) does not equal parent based ' +
607
+ 'context (keys: %s) while mounting %s ' +
608
+ '(see: http://fb.me/react-context-by-parent)',
609
+ Object.keys(ownerBasedContext),
610
+ Object.keys(parentBasedContext),
611
+ displayName
612
+ );
613
+ } else {
614
+ for (key in parentKeys) {
615
+ var key = parentKeys[key];
616
+ warning(
617
+ ownerBasedContext[key] === parentBasedContext[key],
618
+ 'owner-based and parent-based contexts differ ' +
619
+ '(values: `%s` vs `%s`) for key (%s) while mounting %s ' +
620
+ '(see: http://fb.me/react-context-by-parent)',
621
+ ownerBasedContext[key],
622
+ parentBasedContext[key],
623
+ key,
624
+ displayName
625
+ );
626
+ }
627
+ }
628
},
629
630
/**
src/core/__tests__/ReactCompositeComponent-test.js
+42
-1
@@ -1009,7 +1009,7 @@ describe('ReactCompositeComponent', function() {
1009
reactComponentExpect(grandchildInstance).scalarContextEqual({foo: 'bar', depth: 1});
1010
});
1011
1012
- it('warn if contexts differ', function() {
1012
+ it('warn if context keys differ', function() {
1013
var Component = React.createClass({
1014
contextTypes: {
1015
foo: ReactPropTypes.string.isRequired
@@ -1033,6 +1033,47 @@ describe('ReactCompositeComponent', function() {
1033
1034
});
1035
1036
+ it('warn if context values differ', function() {
1037
+ var Parent = React.createClass({
1038
+ childContextTypes: {
1039
+ foo: ReactPropTypes.string
1040
+ },
1041
+
1042
+ getChildContext: function() {
1043
+ return {
1044
+ foo: "bar"
1045
+ };
1046
+ },
1047
+
1048
+ render: function() {
1049
+ return <div>{this.props.children}</div>;
1050
+ }
1051
+ });
1052
+ var Component = React.createClass({
1053
+ contextTypes: {
1054
+ foo: ReactPropTypes.string.isRequired
1055
+ },
1056
+
1057
+ render: function() {
1058
+ return <div />;
1059
+ }
1060
+ });
1061
+
1062
+ var component = React.withContext({foo: 'noise'}, function() {
1063
+ return <Component />
1064
+ });
1065
+
1066
+ ReactTestUtils.renderIntoDocument(<Parent>{component}</Parent>);
1067
+
1068
+ expect(console.warn.mock.calls.length).toBe(2);
1069
+ expect(console.warn.mock.calls[0][0]).toBe(
1070
+ 'Warning: owner-based and parent-based contexts differ ' +
1071
+ '(values: `noise` vs `bar`) for key (foo) while mounting Component ' +
1072
+ '(see: http://fb.me/react-context-by-parent)'
1073
+ );
1074
+
1075
+ });
1076
+
1077
it('should check context types', function() {
1078
var Component = React.createClass({
1079
contextTypes: {