0

我遇到了一个问题,即 react-table(版本 7.1.0)似乎在任何时候需要重新渲染页面时都在重新初始化。以下面的代码(此处运行示例)为例,如果您要更改 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。

4

1 回答 1

0

终于找到答案了。问题是我需要将表的初始化移到渲染逻辑之外(很明显,事后看来)。基本上,我只是创建了一个 ArchiveTable 函数。对于任何偶然发现这一点的人,您可以在此处查看一个工作示例。

function ArchiveTable({ columns, data }) {
    // Add all the initialization and table rendering code here
    // (everything that was originally part of the ArchiveTable initialization)
}
于 2020-06-10T01:14:19.360 回答