@samitouri / QOS-React-2 / commits / 12e765dd27

Revert "Don't mutate passed-in props"

This reverts https://github.com/facebook/react/pull/576 This approach mutates the default props for the instance on each update, which causes incorrect behavior. discussed with @balpert. can look into cloning but this unbreaks.

Paul Shen committed Dec 5, 2013 at 16:50 UTC 12e765dd27ed484e462723419ec269e404349ea6
2 files changed +10 -38
src/core/ReactCompositeComponent.js
+10 -18
@@ -676,7 +676,7 @@ var ReactCompositeComponentMixin = {
676 this._compositeLifeCycleState = CompositeLifeCycle.MOUNTING;
677
678 this._defaultProps = this.getDefaultProps ? this.getDefaultProps() : null;
679 - this.props = this._processProps(this.props);
679 + this._processProps(this.props);
680
681 if (this.__reactAutoBindMap) {
682 this._bindAutoBindMethods();
@@ -844,31 +844,22 @@ var ReactCompositeComponentMixin = {
844
845 /**
846 * Processes props by setting default values for unspecified props and
847 - * asserting that the props are valid. Does not mutate its argument; returns
848 - * a new props object with defaults merged in.
847 + * asserting that the props are valid.
848 *
850 - * @param {object} newProps
851 - * @return {object}
849 + * @param {object} props
850 * @private
851 */
854 - _processProps: function(newProps) {
855 - var props = this._defaultProps;
856 - if (props) {
857 - // To avoid mutating the props that are passed into the constructor, we
858 - // copy onto the object returned by getDefaultProps instead.
859 - for (var propName in newProps) {
860 - if (typeof newProps[propName] !== 'undefined') {
861 - props[propName] = newProps[propName];
862 - }
852 + _processProps: function(props) {
853 + var defaultProps = this._defaultProps;
854 + for (var propName in defaultProps) {
855 + if (typeof props[propName] === 'undefined') {
856 + props[propName] = defaultProps[propName];
857 }
864 - } else {
865 - props = newProps;
858 }
859 var propTypes = this.constructor.propTypes;
860 if (propTypes) {
861 this._checkPropTypes(propTypes, props, ReactPropTypeLocations.prop);
862 }
871 - return props;
863 },
864
865 /**
@@ -920,7 +911,8 @@ var ReactCompositeComponentMixin = {
911
912 var nextProps = this.props;
913 if (this._pendingProps != null) {
923 - nextProps = this._processProps(this._pendingProps);
914 + nextProps = this._pendingProps;
915 + this._processProps(nextProps);
916 this._pendingProps = null;
917
918 this._compositeLifeCycleState = CompositeLifeCycle.RECEIVING_PROPS;
src/core/__tests__/ReactCompositeComponent-test.js
-20
@@ -213,26 +213,6 @@ describe('ReactCompositeComponent', function() {
213 reactComponentExpect(instance3).scalarPropsEqual({key: null});
214 });
215
216 - it('should not mutate passed-in props object', function() {
217 - var Component = React.createClass({
218 - getDefaultProps: function() {
219 - return {key: 'testKey'};
220 - },
221 - render: function() {
222 - return <span />;
223 - }
224 - });
225 -
226 - var inputProps = {};
227 - var instance1 = Component(inputProps);
228 - ReactTestUtils.renderIntoDocument(instance1);
229 - expect(instance1.props.key).toBe('testKey');
230 -
231 - // We don't mutate the input, just in case the caller wants to do something
232 - // with it after using it to instantiate a component
233 - expect(inputProps.key).not.toBeDefined();
234 - });
235 -
216 it('should normalize props with default values', function() {
217 var Component = React.createClass({
218 propTypes: {key: ReactPropTypes.string.isRequired},