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

Remove transferPropsTo

I'd like to outlaw prop mutation altogether, and now seems like a fine time to remove transferPropsTo. Test Plan: jest

Ben Alpert committed Nov 15, 2014 at 16:01 UTC c96ea9abf28d7ffa465feb95c39e3dbb52beb050
7 files changed +22 -255
examples/jquery-bootstrap/js/app.js
+5 -6
@@ -2,12 +2,11 @@
2 // Bootstrap's classes
3 var BootstrapButton = React.createClass({
4 render: function() {
5 - // transferPropsTo() is smart enough to merge classes provided
6 - // to this component.
7 - return this.transferPropsTo(
8 - <a href="javascript:;" role="button" className="btn">
9 - {this.props.children}
10 - </a>
5 + return (
6 + <a {...this.props}
7 + href="javascript:;"
8 + role="button"
9 + className={(this.props.className || '') + ' btn'} />
10 );
11 }
12 });
examples/jquery-mobile/js/app.js
+6 -2
@@ -101,11 +101,15 @@ var JQueryMobilePage = React.createClass({
101 },
102
103 render: function() {
104 - return this.transferPropsTo(React.DOM.div(null,
104 + var props = {};
105 + for (var key in this.props) {
106 + props[key] = this.props[key];
107 + }
108 + return React.DOM.div(props,
109 JQueryMobileHeader({title:'Page ' + this.props.id, headerTheme:this.props.headerTheme}),
110 JQueryMobileContent(null, this.props.children),
111 JQueryMobileFooter(null)
108 - ));
112 + );
113 }
114 });
115
perf/lib/todolist.browser.js
+9 -3
@@ -110,8 +110,14 @@ todolist.NewItemForm = React.createClass({
110 return false;
111 },
112 render: function(){
113 - return this.transferPropsTo(
114 - React.DOM.input({ref:"text", onKeyDown:this.props.onEnter && this._handleNewItemKeyDown})
115 - );
113 + var props = {};
114 + for (var key in this.props) {
115 + if (key !== "onEnter") {
116 + props[key] = this.props[key];
117 + }
118 + }
119 + props.ref = "text";
120 + props.onKeyDown = this.props.onEnter && this._handleNewItemKeyDown;
121 + return React.DOM.input(props);
122 }
123 });
src/class/ReactClass.js
-3
@@ -14,7 +14,6 @@
14 var ReactElement = require('ReactElement');
15 var ReactErrorUtils = require('ReactErrorUtils');
16 var ReactInstanceMap = require('ReactInstanceMap');
17 -var ReactPropTransferer = require('ReactPropTransferer');
17 var ReactPropTypeLocations = require('ReactPropTypeLocations');
18 var ReactPropTypeLocationNames = require('ReactPropTypeLocationNames');
19
@@ -826,7 +825,6 @@ var ReactClassMixin = {
825 var ReactClassBase = function() {};
826 assign(
827 ReactClassBase.prototype,
829 - ReactPropTransferer.Mixin,
828 ReactClassMixin
829 );
830
@@ -834,7 +832,6 @@ assign(
832 * Module for creating composite components.
833 *
834 * @class ReactClass
837 - * @extends ReactPropTransferer
835 */
836 var ReactClass = {
837
src/core/ReactPropTransferer.js
-51
@@ -96,8 +96,6 @@ function transferInto(props, newProps) {
96 */
97 var ReactPropTransferer = {
98
99 - TransferStrategies: TransferStrategies,
100 -
99 /**
100 * Merge two props objects using TransferStrategies.
101 *
@@ -109,55 +107,6 @@ var ReactPropTransferer = {
107 return transferInto(assign({}, oldProps), newProps);
108 },
109
112 - /**
113 - * @lends {ReactPropTransferer.prototype}
114 - */
115 - Mixin: {
116 -
117 - /**
118 - * Transfer props from this component to a target component.
119 - *
120 - * Props that do not have an explicit transfer strategy will be transferred
121 - * only if the target component does not already have the prop set.
122 - *
123 - * This is usually used to pass down props to a returned root component.
124 - *
125 - * @param {ReactElement} element Component receiving the properties.
126 - * @return {ReactElement} The supplied `component`.
127 - * @final
128 - * @protected
129 - */
130 - transferPropsTo: function(element) {
131 - invariant(
132 - element._owner && element._owner.getPublicInstance() === this,
133 - '%s: You can\'t call transferPropsTo() on a component that you ' +
134 - 'don\'t own, %s. This usually means you are calling ' +
135 - 'transferPropsTo() on a component passed in as props or children.',
136 - this.constructor.displayName,
137 - typeof element.type === 'string' ?
138 - element.type :
139 - element.type.displayName
140 - );
141 -
142 - if (__DEV__) {
143 - if (!didWarn) {
144 - didWarn = true;
145 - warning(
146 - false,
147 - 'transferPropsTo is deprecated. ' +
148 - 'See http://fb.me/react-transferpropsto for more information.'
149 - );
150 - }
151 - }
152 -
153 - // Because elements are immutable we have to merge into the existing
154 - // props object rather than clone it.
155 - transferInto(element.props, this.props);
156 -
157 - return element;
158 - }
159 -
160 - }
110 };
111
112 module.exports = ReactPropTransferer;
src/core/__tests__/ReactPropTransferer-test.js deleted
-188
@@ -1,188 +0,0 @@
1 -/**
2 - * Copyright 2013-2014, Facebook, Inc.
3 - * All rights reserved.
4 - *
5 - * This source code is licensed under the BSD-style license found in the
6 - * LICENSE file in the root directory of this source tree. An additional grant
7 - * of patent rights can be found in the PATENTS file in the same directory.
8 - *
9 - * @emails react-core
10 - */
11 -
12 -"use strict";
13 -
14 -var React;
15 -var ReactTestUtils;
16 -var reactComponentExpect;
17 -
18 -var TestComponent;
19 -
20 -describe('ReactPropTransferer', function() {
21 -
22 - beforeEach(function() {
23 - require('mock-modules').dumpCache();
24 -
25 - React = require('React');
26 - ReactTestUtils = require('ReactTestUtils');
27 - reactComponentExpect = require('reactComponentExpect');
28 -
29 - // We expect to get a warning from transferPropsTo since it's deprecated
30 - spyOn(console, 'warn');
31 -
32 - TestComponent = React.createClass({
33 - render: function() {
34 - var result = this.transferPropsTo(
35 - <input
36 - className="textinput"
37 - style={{display: 'block', color: 'green'}}
38 - type="text"
39 - value=""
40 - />
41 - );
42 - expect(console.warn).toHaveBeenCalled();
43 - return result;
44 - }
45 - });
46 - });
47 -
48 - it('should leave explicitly specified properties intact', function() {
49 - var instance = <TestComponent type="radio" />;
50 - instance = ReactTestUtils.renderIntoDocument(instance);
51 -
52 - reactComponentExpect(instance)
53 - .expectRenderedChild()
54 - .toBeComponentOfType('input')
55 - .scalarPropsEqual({
56 - className: 'textinput',
57 - style: {display: 'block', color: 'green'},
58 - type: 'text',
59 - value: ''
60 - });
61 - });
62 -
63 - it('should transfer unspecified properties', function() {
64 - var instance = <TestComponent placeholder="Type here..." />;
65 - instance = ReactTestUtils.renderIntoDocument(instance);
66 -
67 - reactComponentExpect(instance)
68 - .expectRenderedChild()
69 - .toBeComponentOfType('input')
70 - .scalarPropsEqual({placeholder: 'Type here...'});
71 - });
72 -
73 - it('should transfer using merge strategies', function() {
74 - var instance =
75 - <TestComponent
76 - className="hidden_elem"
77 - style={{width: '100%', display: 'none'}}
78 - />;
79 - instance = ReactTestUtils.renderIntoDocument(instance);
80 -
81 - reactComponentExpect(instance)
82 - .expectRenderedChild()
83 - .toBeComponentOfType('input')
84 - .scalarPropsEqual({
85 - className: 'textinput hidden_elem',
86 - style: {
87 - color: 'green',
88 - display: 'block',
89 - width: '100%'
90 - }
91 - });
92 - });
93 -
94 - it('should not transfer children', function() {
95 - var ChildrenTestComponent = React.createClass({
96 - render: function() {
97 - return this.transferPropsTo(<div />);
98 - }
99 - });
100 -
101 - var instance =
102 - <ChildrenTestComponent>
103 - <span>Hello!</span>
104 - </ChildrenTestComponent>;
105 -
106 - instance = ReactTestUtils.renderIntoDocument(instance);
107 - reactComponentExpect(instance)
108 - .expectRenderedChild()
109 - .toBeDOMComponentWithTag('div')
110 - .toBeDOMComponentWithNoChildren();
111 - });
112 -
113 - it('should not transfer ref or key', function() {
114 - var TestComponent = React.createClass({
115 - render: function() {
116 - expect(this.props.ref).toBeUndefined();
117 - expect(this.props.key).toBeUndefined();
118 - return <div />;
119 - }
120 - });
121 - var OuterTestComponent = React.createClass({
122 - render: function() {
123 - return this.transferPropsTo(<TestComponent />);
124 - }
125 - });
126 - var OuterOuterTestComponent = React.createClass({
127 - render: function() {
128 - return <OuterTestComponent ref="testref" key="testkey" />;
129 - }
130 - });
131 -
132 - ReactTestUtils.renderIntoDocument(<OuterOuterTestComponent />);
133 - });
134 -
135 - it('should not transferPropsTo() a component you don\'t own', function() {
136 - var Parent = React.createClass({
137 - render: function() {
138 - return <Child><span /></Child>;
139 - }
140 - });
141 -
142 - var Child = React.createClass({
143 - render: function() {
144 - return this.transferPropsTo(this.props.children);
145 - }
146 - });
147 -
148 - expect(function() {
149 - ReactTestUtils.renderIntoDocument(<Parent />);
150 - }).toThrow(
151 - 'Invariant Violation: ' +
152 - 'Child: You can\'t call transferPropsTo() on a component that you ' +
153 - 'don\'t own, span. ' +
154 - 'This usually means you are calling transferPropsTo() on a component ' +
155 - 'passed in as props or children.'
156 - );
157 - });
158 -
159 - it('uses the default instead of the transferred prop (regress)', function() {
160 -
161 - var Child = React.createClass({
162 -
163 - getDefaultProps: function() {
164 - return {
165 - x: 2
166 - };
167 - },
168 -
169 - render: function() {
170 - expect(this.props.x).toBe(2);
171 - return <div />;
172 - }
173 -
174 - });
175 -
176 - var Parent = React.createClass({
177 -
178 - render: function() {
179 - return this.transferPropsTo(<Child />);
180 - }
181 -
182 - });
183 -
184 - ReactTestUtils.renderIntoDocument(<Parent x={5} />);
185 -
186 - });
187 -
188 -});
src/utils/cloneWithProps.js
+2 -2
@@ -25,8 +25,8 @@ var CHILDREN_PROP = keyOf({children: null});
25 * this is to add a CSS class.
26 *
27 * @param {object} child child component you'd like to clone
28 - * @param {object} props props you'd like to modify. They will be merged
29 - * as if you used `transferPropsTo()`.
28 + * @param {object} props props you'd like to modify. className and style will be
29 + * merged automatically.
30 * @return {object} a clone of child with props merged in.
31 */
32 function cloneWithProps(child, props) {