@samitouri / QOS-React-2 / commits / d7de12fbd8

Preserve prototype with replaceState

Fixes #3418.

Ben Alpert committed May 8, 2015 at 12:04 UTC d7de12fbd8737ab491a2836e7f2ed47ad693eda5
2 files changed +69
src/core/ReactCompositeComponent.js
+4
@@ -623,6 +623,10 @@ var ReactCompositeComponentMixin = {
623 return inst.state;
624 }
625
626 + if (replace && queue.length === 1) {
627 + return queue[0];
628 + }
629 +
630 var nextState = assign({}, replace ? queue[0] : inst.state);
631 for (var i = replace ? 1 : 0; i < queue.length; i++) {
632 var partial = queue[i];
src/core/__tests__/ReactCompositeComponent-test.js
+65
@@ -877,4 +877,69 @@ describe('ReactCompositeComponent', function() {
877 expect(console.error.argsForCall.length).toBe(0);
878 });
879
880 + it('should replace state', function() {
881 + var Moo = React.createClass({
882 + getInitialState: function() {
883 + return {x: 1};
884 + },
885 + render: function() {
886 + return <div />;
887 + }
888 + });
889 +
890 + var moo = ReactTestUtils.renderIntoDocument(<Moo />);
891 + moo.replaceState({y: 2});
892 + expect('x' in moo.state).toBe(false);
893 + expect(moo.state.y).toBe(2);
894 + });
895 +
896 + it('should support objects with prototypes as state', function() {
897 + var NotActuallyImmutable = function(str) {
898 + this.str = str;
899 + };
900 + NotActuallyImmutable.prototype.amIImmutable = function() {
901 + return true;
902 + };
903 + var Moo = React.createClass({
904 + getInitialState: function() {
905 + return new NotActuallyImmutable('first');
906 + },
907 + render: function() {
908 + return <div />;
909 + }
910 + });
911 +
912 + var moo = ReactTestUtils.renderIntoDocument(<Moo />);
913 + expect(moo.state.str).toBe('first');
914 + expect(moo.state.amIImmutable()).toBe(true);
915 +
916 + var secondState = new NotActuallyImmutable('second');
917 + moo.replaceState(secondState);
918 + expect(moo.state.str).toBe('second');
919 + expect(moo.state.amIImmutable()).toBe(true);
920 + expect(moo.state).toBe(secondState);
921 +
922 + moo.setState({str: 'third'});
923 + expect(moo.state.str).toBe('third');
924 + // Here we lose the prototype.
925 + expect(moo.state.amIImmutable).toBe(undefined);
926 +
927 + // When more than one state update is enqueued, we have the same behavior
928 + var fifthState = new NotActuallyImmutable('fifth');
929 + ReactUpdates.batchedUpdates(function() {
930 + moo.setState({str: 'fourth'});
931 + moo.replaceState(fifthState);
932 + });
933 + expect(moo.state).toBe(fifthState);
934 +
935 + // When more than one state update is enqueued, we have the same behavior
936 + var sixthState = new NotActuallyImmutable('sixth');
937 + ReactUpdates.batchedUpdates(function() {
938 + moo.replaceState(sixthState);
939 + moo.setState({str: 'seventh'});
940 + });
941 + expect(moo.state.str).toBe('seventh');
942 + expect(moo.state.amIImmutable).toBe(undefined);
943 + });
944 +
945 });