【问题标题】:looping over array with thead and tbody tags in react在反应中使用thead和tbody标签循环数组
【发布时间】:2018-01-15 02:25:42
【问题描述】:

我正在尝试将 thead 和 tbody 标签添加到我的表中以做出反应。源数据是一个数组,其中第一个索引包含表头,其余为表体。

    return (
      <div>
        {index == 1 && <tbody>}
      <tr key={index}>
        {tableData(false, row.value)}
      </tr>
        {index == pivot.data.table.length && </tbody>}
      </div>
    );

在上面的循环中,我在{index == pivot.data.table.length &amp;&amp; &lt;/tbody&gt;} 得到了意外的令牌

完整代码和沙盒如下:

import React, { Component } from "react";
import { render } from "react-dom";
import Pivot from "quick-pivot";
import { Table } from 'react-bootstrap';

class PivotTable extends Component {
  constructor(props) {
    super(props);
  }

  createTable() {
    const dataArray = [
      ["name", "gender", "house", "age"],
      ["Jon", "m", "Stark", 14],
      ["Arya", "f", "Stark", 10],
      ["Cersei", "f", "Baratheon", 38],
      ["Tywin", "m", "Lannister", 67],
      ["Tyrion", "m", "Lannister", 34],
      ["Joffrey", "m", "Baratheon", 18],
      ["Bran", "m", "Stark", 8],
      ["Jaime", "m", "Lannister", 32],
      ["Sansa", "f", "Stark", 12]
    ];

    const rowsToPivot = ["name"];
    const colsToPivot = ["house", "gender"];
    const aggregationDimension = "age";
    const aggregator = "sum";

    const pivot = new Pivot(
      dataArray,
      rowsToPivot,
      colsToPivot,
      aggregationDimension,
      aggregator
    );

    console.log("pivot.data", pivot.data, "pivot.data.table", pivot.data.table);
    const tableData = (heading, row) => {
      return row.map(cell => {
        if (heading) {
          return (
            <th>
              {cell}
            </th>
          );
        } else {
          return (
            <td>
              {cell}
            </td>
          );
        }
      });
    };

    return pivot.data.table.map((row, index) => {
      if (index == 0) {
        return (
          <thead>
            <tr key={index}>
              {tableData(true, row.value)}
            </tr>
          </thead>
        );
      } else {
        return (
          <div>
            {index == 1 && <tbody>}
          <tr key={index}>
            {tableData(false, row.value)}
          </tr>
            {index == pivot.data.table.length && </tbody>}
          </div>
        );
      }
    });
  }

  render() {
    return (
      <table>
        {this.createTable()}
      </table>
    );
  }
}

render(<PivotTable />, document.getElementById("root"));

沙盒: https://codesandbox.io/s/vgDE6rOEM

我该如何解决这个问题?

我认为最简单的方法是创建一个单独的函数来再次调用数据,创建一个新数组并只创建标题。我这样做的问题是它可能会大大降低性能。

我可以在一个电话中完成这一切吗?或者解决这个问题的最佳方法是什么?

【问题讨论】:

  • 意外的标记可能是 &lt; - 你不能像在 React {...} 中的 JavaScript 表达式中那样输出 HTML 元素
  • @chazsolo 我觉得这很奇怪,因为官方文档提到你可以这样做:facebook.github.io/react/docs/…你知道为什么这不起作用吗?
  • 你说得对……我不确定我在读什么。忽略:)
  • 对不起,我想问一下……为什么桌子里面有&lt;div&gt;
  • @lumio 我添加了它,因为否则我会从反应中得到一个错误,如果我想渲染多个组件,它们应该始终被标签包围。我宁愿排除它们,但我不知道如何。

标签: javascript twitter-bootstrap reactjs meteor


【解决方案1】:

我找到了解决办法:

import React, { Component } from 'react';
import Pivot from 'quick-pivot';
import { Table } from 'react-bootstrap';

export default class PivotTable extends Component {
  constructor(props) {
    super(props);
  }

getGapData 在准备好时获取数据。如果不是,它将返回字符串 'loading'。

  getGapData() {
    //const dataArray = [
    //['name', 'gender', 'house', 'age'],
    //['Jon', 'm', 'Stark', 14],
    //['Arya', 'f', 'Stark', 10],
    //['Cersei', 'f', 'Baratheon', 38],
    //['Tywin', 'm', 'Lannister', 67],
    //['Tyrion', 'm', 'Lannister', 34],
    //['Joffrey', 'm', 'Baratheon', 18],
    //['Bran', 'm', 'Stark', 8],
    //['Jaime', 'm', 'Lannister', 32],
    //['Sansa', 'f', 'Stark', 12],
    //];
    if (this.props.ready) {
      const dataArray = this.props.data;

      const rowsToPivot = ['index'];
      const colsToPivot = ['period'];
      const aggregationDimension = 'visits';
      const aggregator = 'sum';

      const pivot = new Pivot(
        dataArray,
        rowsToPivot,
        colsToPivot,
        aggregationDimension,
        aggregator
      );

      //this.setState({ headerData: pivot.data.table[0] });
      //this.setState({bodyData: pivot.data.table.slice(1) });
      return pivot.data.table;
    } else {
      return 'loading';
    }
  }

在 render() 返回之前,我们执行 getGapData 函数。只需执行一次。

我正在使用 slice 和数组的第一个索引来显示头部和身体数据。我可以用 thead 和 tbody 标签包装这段代码来解决我的问题。

  render() {
    console.log(this.getGapData());
    const gap = this.getGapData();
    return (
      <Table striped bordered condensed hover>
        <thead>
          <tr>
            {gap != 'loading' &&
              gap[0].value.map(data => {
                return (
                  <th>
                    {data}
                  </th>
                );
              })}
          </tr>
        </thead>
        <tbody>
          {gap != 'loading' &&
            gap.slice(1).map(row => {
              return (
                <tr>
                  {row.value.map(data => {
                    return (
                      <td>
                        {data}
                      </td>
                    );
                  })}
                </tr>
              );
            })}
        </tbody>
      </Table>
    );
  }
}

【讨论】:

    【解决方案2】:

    我通常对这种模式使用三元运算符,试试:

    return (
          <div>
            {index == 1 ? <tbody> : <div />}
          <tr key={index}>
            {tableData(false, row.value)}
          </tr>
            {index == pivot.data.table.length ? </tbody> : <div />}
          </div>
        );
    

    【讨论】:

    • 文件中可能有错误...您的 linter 是否报告了任何内容,还是仅在项目构建时才看到?
    • 我尝试使用您的三元运算符(或我的解决方案),当我删除它们时,代码可以工作,但不包含任何 tbody 标签。
    • 哦,等等,我想我知道为什么了——这些语句必须同时嵌入开始标签和结束标签,你不能在一个块中创建开始标签,而在另一个块中创建结束标签。
    • 我认为你可能是对的。我得到了它的工作。将尽可能发布答案。
    猜你喜欢
    • 2011-02-22
    • 2022-12-30
    • 2019-04-06
    • 2010-11-23
    • 1970-01-01
    • 1970-01-01
    • 2018-09-25
    • 1970-01-01
    • 2014-11-06
    相关资源
    最近更新 更多