From 325322898cc413454feede0201b61da1abe1e67e Mon Sep 17 00:00:00 2001 From: Pete Hunt Date: Mon, 7 Oct 2013 14:56:41 -0700 Subject: [PATCH] Throw when calling transferPropsTo() on a component you don't own This is dangerous because it means that data is flowing into the component from two components, only one of which is the actual "owner". While we may be able to figure out how to support this someday, let's be strict and prevent it for now. --- src/core/ReactPropTransferer.js | 8 ++++++ ...ps-test.js => ReactPropTransferer-test.js} | 25 ++++++++++++++++++- 2 files changed, 32 insertions(+), 1 deletion(-) rename src/core/__tests__/{ReactCompositeComponentTransferProps-test.js => ReactPropTransferer-test.js} (83%) diff --git a/src/core/ReactPropTransferer.js b/src/core/ReactPropTransferer.js index 691ed58fc8..db8e675d5b 100644 --- a/src/core/ReactPropTransferer.js +++ b/src/core/ReactPropTransferer.js @@ -19,6 +19,7 @@ "use strict"; var emptyFunction = require('emptyFunction'); +var invariant = require('invariant'); var joinClasses = require('joinClasses'); var merge = require('merge'); @@ -90,6 +91,13 @@ var ReactPropTransferer = { * @protected */ transferPropsTo: function(component) { + invariant( + component.props.__owner__ === this, + 'You can\'t call transferPropsTo() on a component that you don\'t ' + + 'own. This usually means you are calling transferPropsTo() on a ' + + 'component passed in as props or children.' + ); + var props = {}; for (var thatKey in component.props) { if (component.props.hasOwnProperty(thatKey)) { diff --git a/src/core/__tests__/ReactCompositeComponentTransferProps-test.js b/src/core/__tests__/ReactPropTransferer-test.js similarity index 83% rename from src/core/__tests__/ReactCompositeComponentTransferProps-test.js rename to src/core/__tests__/ReactPropTransferer-test.js index 70c7e27532..8b75130005 100644 --- a/src/core/__tests__/ReactCompositeComponentTransferProps-test.js +++ b/src/core/__tests__/ReactPropTransferer-test.js @@ -25,7 +25,7 @@ var reactComponentExpect; var TestComponent; -describe('ReactCompositeComponent-transferProps', function() { +describe('ReactPropTransferer', function() { beforeEach(function() { React = require('React'); @@ -130,4 +130,27 @@ describe('ReactCompositeComponent-transferProps', function() { ReactTestUtils.renderIntoDocument(); }); + + it('should not transferPropsTo() a component you don\'t own', function() { + var Parent = React.createClass({ + render: function() { + return ; + } + }); + + var Child = React.createClass({ + render: function() { + return this.transferPropsTo(this.props.children); + } + }); + + expect(function() { + ReactTestUtils.renderIntoDocument(); + }).toThrow( + 'Invariant Violation: ' + + 'You can\'t call transferPropsTo() on a component that you don\'t own. ' + + 'This usually means you are calling transferPropsTo() on a component ' + + 'passed in as props or children.' + ); + }); });