Create HTML from a for loop in JSX with React.js

I want to bind HTML code for a loop in JSX. That's what my attempt looks like

function renderTemplates(templates){ var html = []; var templateDiv = []; var count = 0; for(var identifier in templates){ if(templates.hasOwnProperty(identifier)){ var templateDetails = templates[identifier]; if(count == 0){ html.push(<Row>); } cols = <Col md={6}>ff </Col>; html.push(cols); if(count == 0){ html.push(</Row>); } count = (count === 1)?0:1; } } return html; } 

I know that this is the wrong syntax, but I canโ€™t figure out how to do it. Basically, I have some data and you want to create html in the mod so that 2 divs are arranged horizontally in 1 line.

+6
source share
2 answers

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) { // catch any leftovers rows.push(<KvpRow key={group[0].key} items={group}/>); } return <table>{rows}</table>; } }); // something silly as a simple example var templates = { a: 'b', c: 'd', e: 'f', g: 'h', i: 'j' }; React.render(<ObjectIDsTable templates={templates} cols="2"/>, document.getElementById('app')); 

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 .

+2
source

In a recent project, I did something similar, but with rows / columns of a table.

 var TableBody = React.createClass({ render: function(){ var columns = this.props.columns; var data = this.props.data; return ( <tbody> {data.map(function(item, idx){ return <TableRow key={idx} data={item} columns={columns}/>; })} </tbody> ) } }); 

My <TableRow /> component is as follows:

 var TableRow = React.createClass({ render: function() { var columns = this.props.columns; var data = this.props.data; var td = function(item) { return columns.map(function(c, i) { return <td key={i}>{item[c]}</td>; }, this); }.bind(this); return ( <tr key={data}>{ td(data) }</tr> ) } }); 
+2
source

Source: https://habr.com/ru/post/982934/


All Articles