Отображать массив объектов построчно с помощью React Table? - PullRequest
0 голосов
/ 02 мая 2020

Я хочу отображать фильмы построчно, не меняя модель 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>
  );
}

В настоящее время он выглядит так:

codesandbox

Вот прямая ссылка на него: https://codesandbox.io/s/modest-sanderson-z0keq?file= / src / App.tsx

Мой список mov ie представляет собой массив объектов, поэтому как я буду отображать его рядом с именем актера? Так это выглядит:

table

1 Ответ

0 голосов
/ 09 мая 2020

Нет другого способа сделать это, кроме как сгладить данные, как упомянул автор библиотеки, вот как я это сделал:

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>
  );
}
...