ETartaren
ETartaren

Reputation: 170

Set the number of cells in the table of components in JSX

I have simple component that represents instances of other component as html table.

class Table extends Component {

    render() {
        const { data } = this.props;

        const articles= data.map((el, i) =>
            <tr><td><Post post={el}/></td></tr>);

        return <table>
                    {articles}
                </table>;

}

Now I have only one table cell per row. I want to place three cells per row, for example.

I tried something like this

const articles = data.map(function(el, i) {
    i++;
    if (i == 1)
        return <tr><td><Post post={el}/></td>;
    else if (i % 3 == 0)
        return <td><Post post={el}/></td></tr>;
    else if (i % 4 == 0)
        return <tr><td><Post post={el}/></td>;
    else
        return <td><Post post={el}/></td>;
});

This is a bad way, anyway. But in JSX this is impossible, because I get error "unterminated JSX contents".

ReactTable is not suitable for me, because I have table of another components, not data grid.

Upvotes: 1

Views: 150

Answers (3)

Estus Flask
Estus Flask

Reputation: 222474

An array of data should be split into chunks with any suitable implementation like Lodash. Then arrays of arrays can be processed:

    return <table>
        {_.chunk(data, 3).map(row => (
            <tr>{row.map(el => (
                 <td><Post post={el}/></td>
            )}</tr>
        )}
    </table>;

Upvotes: 1

Tholle
Tholle

Reputation: 112787

You can use lodash chunk to create an array with arrays where each sub-array represent a row.

Example

class Table extends React.Component {
  render() {
    const { data } = this.props;
    const rows = _.chunk(data, 3);

    const articles = rows.map((row, i) => (
      <tr key={i}>
        {row.map((cell, i) => (
          <td key={i}>{cell}</td>
        ))}
      </tr>
    ));

    return <table>{articles}</table>;
  }
}

ReactDOM.render(
  <Table data={[1, 2, 3, 4, 5, 6, 7]} />,
  document.getElementById("root")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

<div id="root"></div>

Upvotes: 1

ManavM
ManavM

Reputation: 3098

You are going about this the wrong way. A much simpler solution would be to simply manipulate your data into the shape in which you want to work with, and then write your code for rendering it.

That is..convert your data into a 2 dimensional array with 3 columns and ceil(n/3) columns where is the number of elements in your array.

Then you can simply map over the first dimension to create your <tr><tr/> elements and for each row you can map over the 3 elements to create your <td></td> elements.

Note that I am not saying that you cannot do this without creating this intermediate data source, merely that it is always easier if your data structure resembles your component hierarchy.

Upvotes: 0

Related Questions