反应表在渲染时重新初始化

问题描述 投票:0回答:1

我遇到了一个问题,当react-table(7.1.0版本)需要重新渲染页面时,似乎随时都会重新初始化。使用下面的代码(在此运行的例子以PageIndex为例,如果你改变pageIndex的值(通过切换到不同的页面),然后点击Dummy Button,你可以观察到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?换句话说,如果我按了Dummy按钮,我不想让表格重新设置回页面大小为10的第1页。

reactjs react-table react-table-v7
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)
}
© www.soinside.com 2019 - 2024. All rights reserved.