I heard about response patterns, but it still seemed to me that you could create a first-class ForEach component.
My ultimate goal is to make something like this more readable:
<ul> {list.map(function(item, i) { return <li>{item}</li>; })} </ul> // instead? <ul> <ForEach items="{list}"> <li>{item}</li> </ForEach> </ul>
Here is my first serious attempt to skip the props:
var ForEach = React.createClass({ render: function(){ return ( <ul> {this.props.items.map(function(item, i) { return React.Children.map(this.props.children, function(child) { return React.addons.cloneWithProps(child, {item: item}) }) }.bind(this))} </ul> ); } }); var Element = React.createClass({ render: function(){ return ( <li>{this.props.children}</li> ); } });
The task I am facing is what this points out. Thanks to the one-step setup with the debugger, I see that I create cloned elements using this.props.item set, but since {this.props.item} is evaluated in the context of some other method of the rendering component, this not a cloned Element component - this is the ForEach parent.
{this.props.item} will work inside Element.render , but not where I want - I want to be able to pass Element some expression that interpolates the current element.
Perhaps this is not possible in React, or is there a way in which the ForEach component could reset state, like the current element / index, nested elements?
UPDATE I can significantly improve readability with ES6 arrow features. One set of curls goes with return (and possibly also a .bind(this) if you reference this inside a loop).
<ul> {list.map((item, i) => <li>{item}</li> )} </ul>
This is a long way to help with the syntactically awkward execution of the map line.