Merge pull request #2464 from yungsters/immutable

Stop Mutating Merged Lifecycle Results
This commit is contained in:
Timothy Yung
2014-11-18 10:02:07 -08:00
2 changed files with 41 additions and 17 deletions
+20 -16
View File
@@ -22,7 +22,6 @@ var invariant = require('invariant');
var keyMirror = require('keyMirror');
var keyOf = require('keyOf');
var monitorCodeUse = require('monitorCodeUse');
var mapObject = require('mapObject');
var warning = require('warning');
var MIXINS_KEY = keyOf({mixins: null});
@@ -566,24 +565,26 @@ function mixStaticSpecIntoComponent(Constructor, statics) {
* @param {object} two The second object
* @return {object} one after it has been mutated to contain everything in two.
*/
function mergeObjectsWithNoDuplicateKeys(one, two) {
function mergeIntoWithNoDuplicateKeys(one, two) {
invariant(
one && two && typeof one === 'object' && typeof two === 'object',
'mergeObjectsWithNoDuplicateKeys(): Cannot merge non-objects'
'mergeIntoWithNoDuplicateKeys(): Cannot merge non-objects.'
);
mapObject(two, function(value, key) {
invariant(
one[key] === undefined,
'mergeObjectsWithNoDuplicateKeys(): ' +
'Tried to merge two objects with the same key: `%s`. This conflict ' +
'may be due to a mixin; in particular, this may be caused by two ' +
'getInitialState() or getDefaultProps() methods returning objects ' +
'with clashing keys.',
key
);
one[key] = value;
});
for (var key in two) {
if (two.hasOwnProperty(key)) {
invariant(
one[key] === undefined,
'mergeIntoWithNoDuplicateKeys(): ' +
'Tried to merge two objects with the same key: `%s`. This conflict ' +
'may be due to a mixin; in particular, this may be caused by two ' +
'getInitialState() or getDefaultProps() methods returning objects ' +
'with clashing keys.',
key
);
one[key] = two[key];
}
}
return one;
}
@@ -604,7 +605,10 @@ function createMergedResultFunction(one, two) {
} else if (b == null) {
return a;
}
return mergeObjectsWithNoDuplicateKeys(a, b);
var c = {};
mergeIntoWithNoDuplicateKeys(c, a);
mergeIntoWithNoDuplicateKeys(c, b);
return c;
};
}
@@ -586,7 +586,7 @@ describe('ReactCompositeComponent', function() {
expect(function() {
instance = ReactTestUtils.renderIntoDocument(instance);
}).toThrow(
'Invariant Violation: mergeObjectsWithNoDuplicateKeys(): ' +
'Invariant Violation: mergeIntoWithNoDuplicateKeys(): ' +
'Tried to merge two objects with the same key: `x`. This conflict ' +
'may be due to a mixin; in particular, this may be caused by two ' +
'getInitialState() or getDefaultProps() methods returning objects ' +
@@ -594,6 +594,26 @@ describe('ReactCompositeComponent', function() {
);
});
it('should not mutate objects returned by getInitialState()', function() {
var Mixin = {
getInitialState: function() {
return Object.freeze({mixin: true});
}
};
var Component = React.createClass({
mixins: [Mixin],
getInitialState: function() {
return Object.freeze({component: true});
},
render: function() {
return <span />;
}
});
expect(() => {
ReactTestUtils.renderIntoDocument(<Component />);
}).not.toThrow();
});
it('should work with object getInitialState() return values', function() {
var Component = React.createClass({
getInitialState: function() {