72

I have a component called tileGroup that has a property that is a collection(array) of other properties.

The parent component(tileGroup) renders a list of child components by using each set of properties in the collection to create a new component.

Right now I am individually mapping each property from the set to the child component but this will become cumbersome if the property count for a component increases and I'm sure there is a cleaner, simpler way to do it...

How can I pass the full set of properties on to the child component without remapping each property?

Example code:

tileGroupData = {someProperty: 'something', someOtherProperty:'something', 
                tiles: [{vsize:1, hsize:2, etc...}, {vsize:2,hsize:3,title:'whatever'}]};

and then component creation..

var tileGroup = React.createClass({
    render: function() {
       var thechildren = this.props.tiles.map(function(tile)
       {
           //this is what I DON'T want to be doing. 
           return <tileSimple vsize = {tile.vsize} hsize = {tile.hsize} content = {tile.content}/>;

           //what I DO want to be doing
           return <tileSimple allTheProps = {tile}/>; 
       });
Matt Foxx Duncan
  • 2,074
  • 3
  • 23
  • 38

4 Answers4

130

Apparently transferPropsTo is being deprecated. With recent versions of React you can use JSX spread attributes:

return <tileSimple {...tile} />;

More info about this here: Deprecating transferPropsTo

Edgar
  • 6,022
  • 8
  • 33
  • 66
actionshrimp
  • 5,219
  • 3
  • 23
  • 26
31

For those use cases, the easiest thing is to fallback to the JS API instead of JSX.

return tileSimple(tile);

To understand why it works, look at the generated version of the version you want using the JSX Compiler tool ( http://facebook.github.io/react/jsx-compiler.html )

<tileSimple vsize = {tile.vsize} hsize = {tile.hsize} content = {tile.content}/>;
tileSimple( {vsize:  tile.vsize, hsize:  tile.hsize, content:  tile.content});
Vjeux
  • 5,756
  • 4
  • 31
  • 24
  • wouldn't just tileSimple(tile); work? Props are supposed to be immutable so I would suspect a simple object reference would suffice. – Jason Rice Mar 10 '15 at 20:16
  • 1
    On React 13+, you'd use `React.createFactory(tileSimple)(tile);`. See http://fb.me/react-legacyfactory . – Brian Jul 07 '15 at 17:56
  • this will not work if you have to define a `key` while mapping over array of `titleSimple`s – avalanche1 Mar 23 '18 at 03:42
6

You can actually just do the following in your render

return this.transferPropsTo(<tileSimple />);
Ryan Seddon
  • 147
  • 1
  • 4
0

What you propose doing,

return <tileSimple allTheProps={tile} />;

works just fine.

Within the tileSimple component you should then be able to access the properties using syntax like,

var vsize = this.props.allTheProps.vsize;
var hsize = this.props.allTheProps.hsize;
lostriebo
  • 1,483
  • 1
  • 16
  • 25
  • 1
    The problem with that solution is that I will have an ever-increasing set of "wrapper" properties I have to traverse just to go a few nodes down. The solution @Vjeux works though! – Matt Foxx Duncan Jan 04 '14 at 05:17
  • @MattFoxxDuncan I agree that @Vjeux solution is more elegant, however, I don't understand what you mean by an ever-increasing set of wrapper properties? If you passed allTheProps to a child component, you'd still access it the same way (i.e., `this.props.childAllTheProps.vsize`). What am I missing? – lostriebo Jan 05 '14 at 17:26
  • 1
    The component structure I am envisioning entails writing independent components(as is React's philosophy) but having them built by the parent component(if any) they belong to. In a scenario where I have Page Master -> Section -> Tile Group -> Tile(Type) -> Tile Content -> something else -- there is a potential for 5+ wrappers in that chain. This, then, would not be a reasonable object to have to traverse `this.FirstChildPropsWrapper.SecondChildPropsWrapper.ThirdChildPropsWRapper.FourthChildPropsWrapper.etc` – Matt Foxx Duncan Jan 06 '14 at 14:41