在map函数中实现复杂的JSX组件

时间:2017-10-04 23:33:44

标签: reactjs jsx

我的表:

我在MySQL数据库中有两个表。这两个表看起来像这样:

  • group_table(group_id,group_name)
  • item_table(id,group_id,food,qty,price)

使用JOIN操作从数据库中选择数据后,生成的数据如下所示:

enter image description here

我想要制作的内容:

我想生成看起来像这样的输出:

enter image description here

作为一张大桌子,一切都很好:

我目前有React代码,如下所示:

render(){
    const data = this.state.data.map((row) => {
        return (
            <tr key={row['id']}>
                <td>{row['food']}</td>
                <td>{row['qty']}</td>
                <td>{row['price']}</td>
            </tr>
         )
     })

     return (
         <div>
              <table>
              <thead>
                   <tr>
                       <th>Food</th>
                       <th>QTY</th>
                       <th>PRICE</th>
                   </tr>
              </thead>
              <tbody>
                   {data}
              </tbody>
              </table>
          </div>
     )
}

一切正常,一切都显示在一张桌子上。

试图通过group_name打破大表不起作用

到目前为止,我所尝试过的是:

render(){
    const the_tables = this.state.data.map((row) => {
        let table_structure = null
        if (group_name != row['group_name']){
            table_structure = (
                   </tbody>
                </table>
                <h2>{row['group_name']}</h2>
                <table>
                    <thead>
                        <tr>
                            <th>Food</th>
                            <th>QTY</th>
                            <th>Price</th>
                        </tr>
                    </thead>
                    <tbody>
               )
         }

         return (
                {table_structure}
                <tr key={row['id']}>
                   <td>{row['food']}</td>
                   <td>{row['qty']}</td>
                   <td>{row['price']}</td>
                </tr>
             )
       }

       return (
           <div>
                <h1>The main heading</h1>
                {the_tables}
            </div>    
  }

这样,如果在读取下一行时检测到组名的更改,则关闭旧表,并创建一个新表。我还需要弄清楚如何处理第一个表和最后一个表的特殊情况。

我的问题和疑问的来源:

我的主要问题是JSX不允许使用未关闭的元素。那么如何将数据分解为单独的表?如果我不能仅指定JSX结构的一部分,如何处理打开和关闭表标签?我应该采用不同的方法而不是使用.map函数吗?

4 个答案:

答案 0 :(得分:1)

你正在做的事情可能在更像基于模板的框架中工作,比如Angular或Vue,但是React需要一些不同的东西。

您可以做的是将table_stucture创建为React组件,并使用this.props.children来包含表格内容。

例如:

// render()
<TableComponent>
  <tr key={data['id']}>
    <td>{data['item1']}</td>
    <td>{data['item2']}</td>
    <td>{data['item3']}</td>
  </tr>
</TableComponent>

TableComponent看起来像:

// render()
return (
  <table>
    <thead>
    // header rows
    </thead>
    <tbody>
      {this.props.children} // this will output our table data
    </tbody>
  </table>

然后你的循环将返回一堆带有所需内容的TableComponent。您还可以查看Array.protytype.filter()以将数据数组拆分到不同的组中。

见:

答案 1 :(得分:1)

根据Matt Holland的建议,我想出了以下答案:

let group_id = -1;

let data = this.state.data.map((row) => {

    if (row['group_id'] != group_id){
        group_id = row['group_id'];

        let group_rows = this.state.data.filter(group_row =>
            group_row['group_id'] == row['group_id']
        );

        return (
            <TableComponent key={row['group_id']} data={group_rows} group_name={row['group_name']} />

         )
      }
  });

TableComponent类看起来像这样:

import React from 'react';

class TableComponent extends React.Component {

    render(){

            let rows = this.props.data.map((row) => {
                    return (
                            <tr key={row['id']}>
                                    <td>{row['food']}</td>
                                    <td>{row['qty']}</td>
                                    <td>{row['price']}</td>
                            </tr>
                    )

            })

            return (
                    <div>
                            <h2>{this.props.group_name}</h2>
                            <table>
                            <thead>
                                    <tr>
                                            <th>Food</th>
                                            <th>QTY</th>
                                            <th>Price</th>

                                    </tr>
                            </thead>
                            <tbody>
                                    {rows}
                            </tbody>
                            </table>
                    </div>
            )
    }
}

export default TableComponent;

对于此解决方案,我使用.map()函数两次,.filter()函数使用一次。如果有人知道更有效的方式,请随时在这里发布答案。除此之外,这个用于我的目的是正常的。

答案 2 :(得分:0)

表格组件:

  class Table extends Component{

        renderAppointments(){
            return this.props.group_name.map((data, index) => {
                return(
                    <tr key={ index }>
                        <td>{ data.food }</td>
                        <td>{ data.qty }</td>
                        <td>{ data.price }</td>
                    </tr>
                );
            });
        }

        render(){
            return(
                      <table className="table">
                          <thead>
                              <tr>
                                  <td>Food</td>
                                  <td>Qty</td>
                                  <td>Price</td>
                              </tr>
                          </thead>
                          <tbody>
                                { this.renderTableData() }
                          </tbody>
                      </table>
            );
        }
    }

表格组件

Systems.Collections.Specialized.OrderedDictionary

答案 3 :(得分:-2)

您需要关闭JSX并确保使用table_structure和。公开.map函数