Support children and ref for cloneWithProps()

We're not handling these correctly.
This commit is contained in:
Pete Hunt
2014-01-30 16:53:47 -08:00
committed by Paul O’Shannessy
parent b225b34f91
commit 4cbc4b58f6
3 changed files with 81 additions and 2 deletions
+2
View File
@@ -42,6 +42,8 @@ function createTransferStrategy(mergeStrategy) {
/**
* Transfer strategies dictate how props are transferred by `transferPropsTo`.
* NOTE: if you add any more exceptions to this list you should be sure to
* update `cloneWithProps()` accordingly.
*/
var TransferStrategies = {
/**
@@ -126,4 +126,56 @@ describe('cloneWithProps', function() {
cloneWithProps(<Component />, {key: 'xyz'})
);
});
it('should transfer children', function() {
var Component = React.createClass({
render: function() {
expect(this.props.children).toBe('xyz');
return <div />;
}
});
ReactTestUtils.renderIntoDocument(
cloneWithProps(<Component />, {children: 'xyz'})
);
});
it('should shallow clone children', function() {
var Component = React.createClass({
render: function() {
expect(this.props.children).toBe('xyz');
return <div />;
}
});
ReactTestUtils.renderIntoDocument(
cloneWithProps(<Component>xyz</Component>, {})
);
});
it('should support keys and refs', function() {
var Component = React.createClass({
render: function() {
expect(this.props.key).toBe('xyz');
expect(this.props.ref).toBe('xyz');
return <div />;
}
});
var Parent = React.createClass({
render: function() {
var clone =
cloneWithProps(this.props.children, {key: 'xyz', ref: 'xyz'});
return <div>{clone}</div>;
}
});
var Grandparent = React.createClass({
render: function() {
return <Parent><Component key="abc" ref="abc" /></Parent>;
}
});
ReactTestUtils.renderIntoDocument(<Grandparent />);
});
});
+27 -2
View File
@@ -21,6 +21,14 @@
var ReactPropTransferer = require('ReactPropTransferer');
var keyMirror = require('keyMirror');
var SpecialPropsToTransfer = keyMirror({
key: null,
children: null,
ref: null
});
/**
* Sometimes you want to change the props of a child passed to you. Usually
* this is to add a CSS class.
@@ -42,10 +50,27 @@ function cloneWithProps(child, props) {
}
var newProps = ReactPropTransferer.mergeProps(child.props, props);
// ReactPropTransferer does not transfer the `key` prop so do it manually.
if (props.key) {
// ReactPropTransferer does not transfer the `key` prop so do it manually. Do
// not transfer it from the original component.
if (props.hasOwnProperty(SpecialPropsToTransfer.key)) {
newProps.key = props.key;
}
// ReactPropTransferer does not transfer the `children` prop. Transfer it
// from `props` if it exists, otherwise use `child.props.children` if it is
// provided.
if (props.hasOwnProperty(SpecialPropsToTransfer.children)) {
newProps.children = props.children;
} else if (child.props.hasOwnProperty(SpecialPropsToTransfer.children)) {
newProps.children = child.props.children;
}
// ReactPropTransferer does not transfer `ref` so do it manually.
if (props.hasOwnProperty(SpecialPropsToTransfer.ref)) {
newProps.ref = props.ref;
}
return child.constructor.ConvenienceConstructor(newProps);
}