Reputation: 117
I'm trying to render a table that contains a fixed number of columns. I set a width in css, and a fixed number of columns in js code. The the table should be rendered. The problems I'm dealing with are the following: - the code to render N fixed columns in a table is so ugly and I think that there should be a way to do it with clean code - I couldn't find a function that append a component to the child of an element dynamically.
_renderProducts(): ReactElement {
var cols_no = 4;
var cols = [];
for (var col = row_index; col < 0 && col < this.state.products.length; col+=1) {
cols.push(
<LayoutColumn className={cx('XElement/column')} />
);
}
for (var row_index = 0; row_index < this.state.products.length;row_index+=cols_no) {
for (var col = 0; col < cols.length && col < this.state.products.length; col+=1) {
cols[col].appendchild( // THIS DOESN"T EXISTS
<XCard
product={this.state.products[col]} />
)
}
}
return (
<Layout>
{cols}
</Layout>
);
}
I spent several hours trying to find a proper way to do this without success.
Upvotes: 0
Views: 2281
Reputation: 12806
It is not a good idea to manipulate the dom inside react.
To map children, in general, you make sub components that each render a part of the application. Here the map function is used quite often to render the children of a current component.
You can find more examples here: https://facebook.github.io/react/docs/tutorial.html
I think you could change your logic in a similar way like this:
_renderProducts(): ReactElement {
return <Layout>{ this.state.products.map(function(product, idx) {
<LayoutColumn className={cx('XElement/column')} key={idx}>
<XCard product={product} />
</LayoutColumn>
}) }</Layout>;
);
And if you want an example how you could split all elements and split components you could check this snippet
.col0, .col1, .col2, .col3, .col4, .col5 {
width: 120px;
text-align: left;
}
<script type='text/javascript' src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.24/browser.js"></script>
<script type='text/javascript' src="https://fb.me/react-with-addons-0.14.0.js"></script>
<script type='text/javascript' src="https://fb.me/react-dom-0.14.0.js"></script>
<script type="application/javascript;version=1.7" language="JavaScript 1.7">
//<![CDATA[
var Header = React.createClass({
propTypes: {
title: React.PropTypes.string,
className: React.PropTypes.string
},
render: function() {
var { title, className } = this.props;
return <th className={className}>{title}</th>;
}
});
var ElementRow = React.createClass({
propTypes: {
values: React.PropTypes.arrayOf(React.PropTypes.any)
},
render: function() {
var { values } = this.props;
if (!values) {
return null;
}
return <tr>{ values.map(function(i, k) {
return <Element className={'col' + i} value={i} key={k} />;
}) }</tr>;
}
});
var Element = React.createClass({
propTypes: {
value: React.PropTypes.any,
className: React.PropTypes.string
},
render: function() {
var { value, className } = this.props || '';
return <td className={className}>{value}</td>
}
});
var Example = React.createClass({
propTypes: {
columns: React.PropTypes.array,
rows: React.PropTypes.arrayOf(React.PropTypes.array)
},
renderHeaders: function(columns) {
if (!columns) {
return null;
}
return columns.map(function(i, k) {
return <Header title={i} key={k} className={'col' + k} />;
});
},
renderBody: function(rows) {
if (!rows) {
return null;
}
return <tbody>{ rows.map(function(i, k) {
return <ElementRow values={i} key={k} />;
}) }</tbody>;
},
render: function() {
var { columns, rows } = this.props;
if (!columns) {
return null;
}
return <table><thead>
<tr>{this.renderHeaders(columns)}</tr>
</thead>
{this.renderBody(rows)}
</table>;
}
});
var table = {
columns: ['column1', 'column2', 'column3', 'column4', 'column5'],
rows: [
['row1 - 1', 'row1 - 2', 'row1 - 3', 'row1 - 4', 'row1 - 5'],
['row2 - 1', 'row2 - 2', 'row2 - 3', 'row2 - 4', 'row2 - 5'],
['row3 - 1', 'row3 - 2', 'row3 - 3', 'row3 - 4', 'row3 - 5']
]
};
ReactDOM.render(
<Example {...table} />,
document.getElementById('container')
);
//]] >
</script>
<script src="https://facebook.github.io/react/js/jsfiddle-integration-babel.js"></script>
<div id="container">
<!-- This element's contents will be replaced with your component. -->
</div>
Upvotes: 1