react-table在渲染时重新初始化

时间:2020-06-10 00:01:19

标签: reactjs react-table react-table-v7

我遇到一个问题,即每当需要重新呈现页面时,react-table(版本7.1.0)似乎都在重新初始化。以下面的代码(running example here)为例,如果要更改pageIndex值(通过切换到另一页),然后单击“虚拟按钮”,则可以观察到pageIndex重置为默认值。 0。如果您修改pageSize,也会发生同样的事情,因为它在每次需要重新呈现页面时都会自动将其重置为默认值10。

import React, { useState } from "react";
import makeData from "./makeData";
import { useTable, usePagination } from "react-table";
import { ButtonToolbar, Button, Table } from "react-bootstrap";

// Nonsense function to force page to be rendered
function useForceUpdate() {
  const [value, setValue] = useState(0);

  return () => setValue(value => ++value);
}

export default function App() {
  const forceUpdate = useForceUpdate();
  const columns = React.useMemo(
    () => [
      {
        Header: "Name",
        columns: [
          {
            Header: "First Name",
            accessor: "firstName"
          },
          {
            Header: "Last Name",
            accessor: "lastName"
          }
        ]
      },
      {
        Header: "Info",
        columns: [
          {
            Header: "Age",
            accessor: "age"
          },
          {
            Header: "Visits",
            accessor: "visits"
          },
          {
            Header: "Status",
            accessor: "status"
          },
          {
            Header: "Profile Progress",
            accessor: "progress"
          }
        ]
      }
    ],
    []
  );

  const data = React.useMemo(() => makeData(100000), []);
  let ArchiveTable = ({ columns, data }) => {
    const {
      getTableProps,
      getTableBodyProps,
      headerGroups,
      prepareRow,
      page,
      canPreviousPage,
      canNextPage,
      pageOptions,
      pageCount,
      gotoPage,
      nextPage,
      previousPage,
      setPageSize,
      state: { pageIndex, pageSize }
    } = useTable(
      {
        columns,
        data
      },
      usePagination
    );

    return (
      <div style={{ textAlign: "center" }}>
        <Table striped bordered {...getTableProps()} className="datasets">
          <thead>
            {headerGroups.map(headerGroup => (
              <tr {...headerGroup.getHeaderGroupProps()}>
                {headerGroup.headers.map(column => (
                  <th {...column.getHeaderProps()}>
                    {column.render("Header")}
                  </th>
                ))}
              </tr>
            ))}
          </thead>
          <tbody {...getTableBodyProps()}>
            {page.map((row, i) => {
              prepareRow(row);

              return (
                <tr
                  {...row.getRowProps()}
                  className={row.isSelected ? "selected" : row.className}
                >
                  {row.cells.map(cell => {
                    return (
                      <td {...cell.getCellProps()}>{cell.render("Cell")}</td>
                    );
                  })}
                </tr>
              );
            })}
          </tbody>
        </Table>
        <div className="pagination" style={{ display: "inline-block" }}>
          <ButtonToolbar>
            <Button
              variant="light"
              onClick={() => gotoPage(0)}
              disabled={!canPreviousPage}
              size="small"
            >
              <span>&lt;&lt;</span>
            </Button>
            <Button
              variant="light"
              onClick={previousPage}
              disabled={!canPreviousPage}
              size="small"
            >
              <span>&lt;</span>
            </Button>
            <select
              value={pageSize}
              onChange={e => {
                setPageSize(Number(e.target.value));
              }}
            >
              {[5, 10, 20, 30, 40, 50].map(pageSize => (
                <option key={pageSize} value={pageSize}>
                  Show {pageSize}
                </option>
              ))}
            </select>
            <Button
              variant="light"
              onClick={nextPage}
              disabled={!canNextPage}
              size="small"
            >
              <span>&gt;</span>
            </Button>
            <Button
              variant="light"
              onClick={() => gotoPage(pageCount - 1)}
              disabled={!canNextPage}
              size="small"
            >
              <span>&gt;&gt;</span>
            </Button>
          </ButtonToolbar>
          <span>
            Page <strong>{pageOptions.length === 0 ? 0 : pageIndex + 1}</strong>{" "}
            of <strong>{pageOptions.length}</strong>
          </span>
        </div>
      </div>
    );
  };

  return (
    <div className="App">
      <ArchiveTable data={data} columns={columns} />
      <button onClick={forceUpdate}>Dummy Button</button>
    </div>
  );
}

要解决此问题,我完全不知所措。设置所有内容的正确方法是什么,以使我不必在每次必须重新呈现页面时都重新初始化react-table?换句话说,如果我按下“虚拟按钮”,我不希望表格重置为页面大小为10的第1页。

1 个答案:

答案 0 :(得分:0)

最终弄清楚答案。问题是我需要将表的初始化移到呈现逻辑之外(事后看来很明显)。基本上,我只是创建了ArchiveTable函数。对于偶然发现此问题的任何人,您可以check here作为一个有效的例子。

function ArchiveTable({ columns, data }) {
    // Add all the initialization and table rendering code here
    // (everything that was originally part of the ArchiveTable initialization)
}