使用 React Table 逐行显示对象数组?

Display an array of objects row-by-row using React Table?

我想在不更改 data 模型的情况下逐行显示电影。

这是我的代码:

import * as React from "react";
import { useTable } from "react-table";

const borderStyle = {
  border: "1px dashed navy"
};

export default function App() {
  const data = React.useMemo(
    () => [
      {
        actor: "Johnny Depp",
        movies: [
          {
            name: "Pirates of the Carribean 1"
          },
          {
            name: "Pirates of the Carribean 2"
          },
          {
            name: "Pirates of the Carribean 3"
          },
          {
            name: "Pirates of the Carribean 4"
          }
        ]
      }
    ],
    []
  );
  const columns = React.useMemo(
    () => [
      {
        Header: "Actor",
        accessor: "actor",
      },
      {
        Header: "Movies",
        accessor: (row, index) => {
          console.log({ row });
          // i want to display this row-by-row instead of in 1-row without changing data model
          return row.movies.map(movie => movie.name);
        }
      }
    ],
    []
  );
  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    rows,
    prepareRow
  } = useTable({ columns, data });
  return (
    <table {...getTableProps()}>
      <thead>
        {headerGroups.map(headerGroup => (
          <tr {...headerGroup.getHeaderGroupProps()}>
            {headerGroup.headers.map(column => (
              <th {...column.getHeaderProps()} style={borderStyle}>
                {column.render("Header")}
              </th>
            ))}
          </tr>
        ))}
      </thead>
      <tbody {...getTableBodyProps()}>
        {rows.map((row, i) => {
          prepareRow(row);
          if (i == 0) {
            console.log({ row });
          }
          return (
            <tr {...row.getRowProps()}>
              {row.cells.map((cell, j) => {
                if (i == 0 && j < 2) {
                  console.log({ cell, i, j });
                }
                return (
                  <td
                    {...cell.getCellProps()}
                    style={borderStyle}
                  >
                    {cell.render("Cell")}
                  </td>
                );
              })}
            </tr>
          );
        })}
      </tbody>
    </table>
  );
}

目前看起来像:

这是直接 link 到它:https://codesandbox.io/s/modest-sanderson-z0keq?file=/src/App.tsx

我的电影列表是一个对象数组,那么如何将它显示在演员姓名旁边?所以它看起来像:

没有其他方法可以做到这一点,只能像库的作者提到的那样将数据展平,所以我是这样做的:

import * as React from "react";
import { useTable } from "react-table";

type Data = {
  actor: string;
  movie: string;
}

const borderStyle = {
  border: "1px dashed navy"
};

export default function App() {
  const origData = [
    {
      actor: "Johnny Depp",
      movies: [
        {
          name: "Pirates of the Carribean 1"
        },
        {
          name: "Pirates of the Carribean 2"
        },
        {
          name: "Pirates of the Carribean 3"
        },
        {
          name: "Pirates of the Carribean 4"
        }
      ]
    }
  ];
  const newData: Array<Data> = [];
  origData.forEach(actorObj => {
    actorObj.movies.forEach(movie => {
      newData.push({
        actor: actorObj.actor,
        movie: movie.name
      });
    });
  });
  const data = React.useMemo(() => newData, []);
  const columns = React.useMemo(
    () => [
      {
        Header: "Actor",
        accessor: "actor"
      },
      {
        Header: "Movies",
        accessor: "movie"
      }
    ],
    []
  );
  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    rows,
    prepareRow
  } = useTable({ columns, data });
  return (
    <table {...getTableProps()}>
      <thead>
        {headerGroups.map(headerGroup => (
          <tr {...headerGroup.getHeaderGroupProps()}>
            {headerGroup.headers.map(column => (
              <th {...column.getHeaderProps()} style={borderStyle}>
                {column.render("Header")}
              </th>
            ))}
          </tr>
        ))}
      </thead>
      <tbody {...getTableBodyProps()}>
        {rows.map((row, i) => {
          prepareRow(row);
          if (i == 0) {
            console.log({ row });
          }
          return (
            <tr {...row.getRowProps()}>
              {row.cells.map((cell, j) => {
                if (i == 0 && j < 2) {
                  console.log({ cell, i, j });
                }
                return (
                  <td
                    rowSpan={cell.rowSpan}
                    {...cell.getCellProps()}
                    style={borderStyle}
                  >
                    {cell.render("Cell")}
                  </td>
                );
              })}
            </tr>
          );
        })}
      </tbody>
    </table>
  );
}