adinutzyc21 adinutzyc21 - 11 days ago 6
React JSX Question

Compositing html code in reactjs

I am currently trying to render a table from data in React, and I have this:

import React, { Component, PropTypes } from 'react';

// Column component - represents columns in the table
export default class Table extends Component {
setHtmlHead(data) {
var html = "";
for (var property in data) {
if (data.hasOwnProperty(property)) {
html += "<th>" + data[property] + "</th>";
}
}
return "<tr>" + html + "</tr>";
}

setHtmlBody(data) {
var html = "";
for (var i = 0, len = data.length; i < len; i++) {
var row = data[i];
html += "<tr>";
for (var property in row) {
if (row.hasOwnProperty(property)) {
html += "<td>" + row[property] + "</td>";
}
}
html += "</tr>";
}
return html;
}

render() {
return (
<table className='table table-bordered'>
<thead dangerouslySetInnerHTML={{ __html: this.setHtmlHead(this.props.data[0]) }} />
<tbody dangerouslySetInnerHTML={{ __html: this.setHtmlBody(this.props.data.slice(1), "td") }} />
</table>
);
}
}


As you can see, I am doing this mostly wrong, probably (hopefully?). There has to be a way to dynamically add
<th>
es in the render function, but I cannot figure it out.

I want to be able to do a for loop, like in the
setHtml()
functions above, but instead of appending strings I want to append html-code. Also, probably inside the
render
function?

I want to also be able to do something like
<th><Button /></th>
, and have the
Button
render correctly (
Button
is defined in a different jsx file and renders a button, but if I use strings or
toString()
, it gets converted to
[Object object]
.

So, is there a way to composit html-data in React? I know of
map
but I wasn't able to make it do what I want it to do... especially since I want the last column to be a
Button
so not part of the data (though I guess I could get it there using CSS instead of making it be a column).

Answer

In React you would usually do something like this:

setHtmlHead(data) {
    var html = [];
    for (var property in data) {
        if (data.hasOwnProperty(property)) {
            html.push(<th key={property}>{data[property]}</th>);
        }
    }
    return <tr>{html}</tr>;
}

And then in the main part

<thead>{this.setHtmlHead(this.props.data[0])}</thead>

This way you're working with actual objects and not just writing raw HTML out. And if you want a Button in the th just put it in there.