Two things jump out of me when I look at your code.
First, you are returning an array of React components from the renderTemplates function. This may be ok depending on how you use the output. The key to remembering is that the return value from the component's render function must be one React component (for example, if you wrap this result with another JSX tag, you're fine.)
Secondly, it looks like you are not allowing the component-level data flow from top to bottom; in particular, that you are not using the Row component to pass data to the column components. This is what makes recording your loop difficult. Instead of trying to manage both rows and columns, you only need to pass the data needed for one row to the Row component. The Row component then passes each piece of data to the column component. This eliminates the need to juggle opening and closing tags and simplifies common code.
The following is an example implementation of what I described. I use table-related tags for rendering, but you can use divs or whatever is most suitable for you. At the time of this writing, there is little information about what is in the templates, so I created a stupid example for use.
var KvpColumn = React.createClass({ render: function() { return <td>{this.props.kvp.key}: {this.props.kvp.value}</td>; } }); var KvpRow = React.createClass({ render: function() { return ( <tr> {this.props.items.map(function(item) { return <KvpColumn key={item.key} kvp={item}/>; })} </tr> ); } }); var ObjectIDsTable = React.createClass({ render: function() { var templates = this.props.templates; var propertyNames = Object.getOwnPropertyNames(templates); var group = []; var rows = []; var cols = Number(this.props.cols) || 2; for(var i = 0; i < propertyNames.length; i++) { var key = propertyNames[i]; group.push({key: key, value: templates[key]}); if(group.length === cols) { rows.push(<KvpRow key={group[0].key} items={group}/>); group = []; } } if(group.length > 0) {
If you have access to Underscore or lodash, you can simplify the logic in ObjectIDsTable a bit (and generally avoid writing loops!):
var ObjectIDsTable = React.createClass({ render: function() { var templates = this.props.templates; var rows = _.chain(Object.getOwnPropertyNames(templates)) .map(function(key) { return { key: key, value: templates[key] }; }) .chunk(this.props.cols || 2) .map(function(group) { return <KvpRow key={group[0].key} items={group}/>; }) .value(); return <table>{rows}</table>; } });
You can see it in action on Plunker .
source share