diff --git a/src/core/ReactCompositeComponent.js b/src/core/ReactCompositeComponent.js
index 40a94b8bed..fab9ffd78d 100644
--- a/src/core/ReactCompositeComponent.js
+++ b/src/core/ReactCompositeComponent.js
@@ -547,10 +547,14 @@ function mergeObjectsWithNoDuplicateKeys(one, two) {
*/
function createMergedResultFunction(one, two) {
return function mergedResult() {
- return mergeObjectsWithNoDuplicateKeys(
- one.apply(this, arguments),
- two.apply(this, arguments)
- );
+ var a = one.apply(this, arguments);
+ var b = two.apply(this, arguments);
+ if (a == null) {
+ return b;
+ } else if (b == null) {
+ return a;
+ }
+ return mergeObjectsWithNoDuplicateKeys(a, b);
};
}
diff --git a/src/core/__tests__/ReactCompositeComponent-test.js b/src/core/__tests__/ReactCompositeComponent-test.js
index ed75168de4..d7fa8feb80 100644
--- a/src/core/__tests__/ReactCompositeComponent-test.js
+++ b/src/core/__tests__/ReactCompositeComponent-test.js
@@ -477,30 +477,6 @@ describe('ReactCompositeComponent', function() {
);
});
- it('should throw with bad getInitialState() return values', function() {
- var Mixin = {
- getInitialState: function() {
- return null;
- }
- };
- var Component = React.createClass({
- mixins: [Mixin],
- getInitialState: function() {
- return {x: true};
- },
- render: function() {
- return ;
- }
- });
- var instance = ;
- expect(function() {
- ReactTestUtils.renderIntoDocument(instance);
- }).toThrow(
- 'Invariant Violation: mergeObjectsWithNoDuplicateKeys(): ' +
- 'Cannot merge non-objects'
- );
- });
-
it('should work with object getInitialState() return values', function() {
var Component = React.createClass({
getInitialState: function() {
@@ -546,7 +522,77 @@ describe('ReactCompositeComponent', function() {
return ;
}
});
- expect(() => ).not.toThrow();
+ expect(
+ () => ReactTestUtils.renderIntoDocument()
+ ).not.toThrow();
+ });
+
+ it('should work with a null getInitialState return value and a mixin', () => {
+ var Component;
+ var instance;
+
+ var Mixin = {
+ getInitialState: function() {
+ return {foo: 'bar'};
+ }
+ };
+ Component = React.createClass({
+ mixins: [Mixin],
+ getInitialState: function() {
+ return null;
+ },
+ render: function() {
+ return ;
+ }
+ });
+ expect(
+ () => ReactTestUtils.renderIntoDocument()
+ ).not.toThrow();
+
+ instance = ;
+ ReactTestUtils.renderIntoDocument(instance);
+ expect(instance.state).toEqual({foo: 'bar'});
+
+ // Also the other way round should work
+ var Mixin2 = {
+ getInitialState: function() {
+ return null;
+ }
+ };
+ Component = React.createClass({
+ mixins: [Mixin2],
+ getInitialState: function() {
+ return {foo: 'bar'};
+ },
+ render: function() {
+ return ;
+ }
+ });
+ expect(
+ () => ReactTestUtils.renderIntoDocument()
+ ).not.toThrow();
+
+ instance = ;
+ ReactTestUtils.renderIntoDocument(instance);
+ expect(instance.state).toEqual({foo: 'bar'});
+
+ // Multiple mixins should be fine too
+ Component = React.createClass({
+ mixins: [Mixin, Mixin2],
+ getInitialState: function() {
+ return {x: true};
+ },
+ render: function() {
+ return ;
+ }
+ });
+ expect(
+ () => ReactTestUtils.renderIntoDocument()
+ ).not.toThrow();
+
+ instance = ;
+ ReactTestUtils.renderIntoDocument(instance);
+ expect(instance.state).toEqual({foo: 'bar', x: true});
});
it('should work with object getInitialState() return values', function() {