Allow null return values for functions to-be-merged.
cpojer committed
Jan 14, 2014 at 10:45 UTC
c885abbf21fb04ae286f45b0fa5cc433310f8d8c
2 files changed
+79
-29
src/core/ReactCompositeComponent.js
+8
-4
@@ -547,10 +547,14 @@ function mergeObjectsWithNoDuplicateKeys(one, two) {
547
*/
548
function createMergedResultFunction(one, two) {
549
return function mergedResult() {
550
- return mergeObjectsWithNoDuplicateKeys(
551
- one.apply(this, arguments),
552
- two.apply(this, arguments)
553
- );
550
+ var a = one.apply(this, arguments);
551
+ var b = two.apply(this, arguments);
552
+ if (a == null) {
553
+ return b;
554
+ } else if (b == null) {
555
+ return a;
556
+ }
557
+ return mergeObjectsWithNoDuplicateKeys(a, b);
558
};
559
}
560
src/core/__tests__/ReactCompositeComponent-test.js
+71
-25
@@ -477,30 +477,6 @@ describe('ReactCompositeComponent', function() {
477
);
478
});
479
480
- it('should throw with bad getInitialState() return values', function() {
481
- var Mixin = {
482
- getInitialState: function() {
483
- return null;
484
- }
485
- };
486
- var Component = React.createClass({
487
- mixins: [Mixin],
488
- getInitialState: function() {
489
- return {x: true};
490
- },
491
- render: function() {
492
- return <span />;
493
- }
494
- });
495
- var instance = <Component />;
496
- expect(function() {
497
- ReactTestUtils.renderIntoDocument(instance);
498
- }).toThrow(
499
- 'Invariant Violation: mergeObjectsWithNoDuplicateKeys(): ' +
500
- 'Cannot merge non-objects'
501
- );
502
- });
503
-
480
it('should work with object getInitialState() return values', function() {
481
var Component = React.createClass({
482
getInitialState: function() {
@@ -546,7 +522,77 @@ describe('ReactCompositeComponent', function() {
522
return <span />;
523
}
524
});
549
- expect(() => <Component />).not.toThrow();
525
+ expect(
526
+ () => ReactTestUtils.renderIntoDocument(<Component />)
527
+ ).not.toThrow();
528
+ });
529
+
530
+ it('should work with a null getInitialState return value and a mixin', () => {
531
+ var Component;
532
+ var instance;
533
+
534
+ var Mixin = {
535
+ getInitialState: function() {
536
+ return {foo: 'bar'};
537
+ }
538
+ };
539
+ Component = React.createClass({
540
+ mixins: [Mixin],
541
+ getInitialState: function() {
542
+ return null;
543
+ },
544
+ render: function() {
545
+ return <span />;
546
+ }
547
+ });
548
+ expect(
549
+ () => ReactTestUtils.renderIntoDocument(<Component />)
550
+ ).not.toThrow();
551
+
552
+ instance = <Component />;
553
+ ReactTestUtils.renderIntoDocument(instance);
554
+ expect(instance.state).toEqual({foo: 'bar'});
555
+
556
+ // Also the other way round should work
557
+ var Mixin2 = {
558
+ getInitialState: function() {
559
+ return null;
560
+ }
561
+ };
562
+ Component = React.createClass({
563
+ mixins: [Mixin2],
564
+ getInitialState: function() {
565
+ return {foo: 'bar'};
566
+ },
567
+ render: function() {
568
+ return <span />;
569
+ }
570
+ });
571
+ expect(
572
+ () => ReactTestUtils.renderIntoDocument(<Component />)
573
+ ).not.toThrow();
574
+
575
+ instance = <Component />;
576
+ ReactTestUtils.renderIntoDocument(instance);
577
+ expect(instance.state).toEqual({foo: 'bar'});
578
+
579
+ // Multiple mixins should be fine too
580
+ Component = React.createClass({
581
+ mixins: [Mixin, Mixin2],
582
+ getInitialState: function() {
583
+ return {x: true};
584
+ },
585
+ render: function() {
586
+ return <span />;
587
+ }
588
+ });
589
+ expect(
590
+ () => ReactTestUtils.renderIntoDocument(<Component />)
591
+ ).not.toThrow();
592
+
593
+ instance = <Component />;
594
+ ReactTestUtils.renderIntoDocument(instance);
595
+ expect(instance.state).toEqual({foo: 'bar', x: true});
596
});
597
598
it('should work with object getInitialState() return values', function() {