【问题标题】:reactjs paging through the tablereactjs通过表格分页
【发布时间】:2020-02-13 15:32:03
【问题描述】:

我正在使用 api 列出数据。 我用 reactstrap 表向用户展示我收到的数据。 但我想分页。

一页最多显示6条记录,其他记录显示在后面的页面中。

import React, { Component, useState } from "react";
import withAuth from "../../components/helpers/withAuth";
import {
  Button,
  Card,
  CardBody,
  CardHeader,
  Col,
  Pagination,
  PaginationItem,
  PaginationLink,
  Row,
  Table,
} from "reactstrap";

class CustomerDebt extends Component {
  constructor(props) {
    super(props);

    this.domain = `http://127.0.0.1:8000`;
    this.state = {
      isLoaded: true,

      items: [], //Customer Debt Items
    };
  }

  async componentDidMount() {
    //customer debt list
    await fetch(
      `${this.domain}/api/debt/list?customer=` +
        this.props.customerInfo.customer.id,
      {
        headers: {
          Authorization: `Bearer ${localStorage.getItem("token")}`,
          "Content-Type": "application/json"
        }
      }
    )
      .then(res => {
        if (res.ok) {
          return res.json();
        } else {
          return res.json().then(err => Promise.reject(err));
        }
      })
      .then(json => {
        this.setState({
          items: json,
        });
        this.abortController.abort();
      })
      .catch(error => {
      return error;
      });
  }

  render() {
    const { isLoaded, items } = this.state;
    if (!isLoaded) {
      return <div>Loading...</div>;
    } else {
      return (
        <div className={"animated fadeIn container-fluid"}>
          <Row>
            <Col>
              <Card>
                <CardHeader>
                  <i className="fa fa-align-justify" /> Müşteri Borcu
                </CardHeader>
                <CardBody>
                  <Table hover bordered striped responsive size="sm">
                    <thead>
                      <tr>
                        <th width={"10"} />
                        <th width={"15"}>No</th>
                        <th style={{ display: "none" }}>User</th>
                        <th style={{ display: "none" }}>Key</th>
                        <th style={{ display: "none" }}>CreatedUserKey</th>
                        <th width={"40"}>Total debt</th>
                        <th width={"40"}>Received amount</th>
                        <th scope={"row"}>Description</th>
                        <th width={"20"}>Payment Date</th>
                      </tr>
                    </thead>
                    <tbody>
                      {items.map(item => {
                        return (
                          <tr key={item.id}>
                            <td>{item.id}</td>
                            <td style={{ display: "none" }}>{item.user}</td>
                            <td style={{ display: "none" }}>{item.debtKey}</td>
                            <td style={{ display: "none" }}> {" "} {item.createduserKey}{" "} </td>
                            <td>{item.totalDebt}</td>
                            <td>{item.receivedAmount}</td>
                            <td>{item.description}</td>
                            <td> {new Date(item.paymentDate).toLocaleString()} </td>
                          </tr>
                        );
                      })}
                    </tbody>
                  </Table>
                  <nav>
                    <Pagination>
                      <PaginationItem>
                        <PaginationLink previous tag="button">
                          Back
                        </PaginationLink>
                      </PaginationItem>
                      <PaginationItem active>
                        <PaginationLink tag="button">1</PaginationLink>
                      </PaginationItem>
                      <PaginationItem>
                        <PaginationLink tag="button">2</PaginationLink>
                      </PaginationItem>
                      <PaginationItem>
                        <PaginationLink tag="button">3</PaginationLink>
                      </PaginationItem>
                      <PaginationItem>
                        <PaginationLink tag="button">4</PaginationLink>
                      </PaginationItem>
                      <PaginationItem>
                        <PaginationLink next tag="button">
                          Next
                        </PaginationLink>
                      </PaginationItem>
                      <PaginationItem></PaginationItem>
                    </Pagination>
                  </nav>
                </CardBody>
              </Card>
            </Col>
          </Row>
        </div>
      );
    }
  }
}
export default CustomerDebt;

【问题讨论】:

  • 谷歌查询“reactstrap 分页”为我返回了这篇文章:medium.com/about-coding/…。这基本上就是您正在寻找的确切答案。
  • 是的,我知道,但我不能。 reactjs 刚刚开始

标签: javascript reactjs pagination reactstrap


【解决方案1】:

首先,您需要创建两个变量来帮助您跟踪当前页面和表格的大小。我们称他们为pageSizepageIndex

class App extends React.Component {
  state = {
    pageSize: 2, // <- 2 items will be shown on single page
    pageIndex: 0, // 0 is a default page to show
    items: []
  };
...

然后你需要从外部来源获取一些数据。在我的示例中,我只是创建了一个模拟数组并将其设置为状态。

...
  componentDidMount() {
    const data = [
      { id: 1, name: "Roman" },
      { id: 2, name: "Oleh" },
      { id: 3, name: "Vitalii" },
      { id: 4, name: "Mikhail" },
      { id: 5, name: "Vladislav" },
      { id: 6, name: "Anton" },
      { id: 7, name: "Yurii" },
      { id: 8, name: "Volodymir" },
      { id: 9, name: "Taras" }
    ];

    this.setState({ items: data });
  }
...

之后,您需要创建辅助函数并在其中放置表格导航逻辑。让我们将它们命名为 handlePrevPageClickhandleNextPageClick

handlePrevPageClick 应该减少点击时的当前索引。此外,我们需要防止用户滚动太多。所以,如果pageIndex 不为0 - 减少,否则停止减少。

handleNextPageClick 的逻辑应该与handlePrevPageClick 完全相同。唯一相反的是它。不要让用户过度滚动您的表格。为此,我们需要了解我们有多少页。通过除以this.state.items / this.state.pageSize,我们将得到可用页面的总数。假设我们的表有 12 个项目,页面大小为 5。所以,12 / 5 = 2.4。这意味着我们将有 2 个页面已满,剩下 4 个项目。通过使用Math.ceil(12 / 5),我们将得到 3 - 是表的可用总页数的整数。之后,我们只是添加简单的条件,如果pageIndex pageIndex,否则停止。

...
  handlePrevPageClick(event) {
    this.setState(prevState => ({
      pageIndex: prevState.pageIndex > 0 ? prevState.pageIndex - 1 : 0
    }));
  }

  handleNextPageClick(event) {
    this.setState(prevState => ({
      pageIndex:
        prevState.pageIndex <
        Math.ceil(prevState.items.length / prevState.pageSize)
          ? prevState.pageIndex + 1
          : prevState.pageIndex
    }));
  }

最后的想法是使用正确的行来呈现您的表格。为此,您可以使用.slice(...)。第一个参数是页面的左边界,第二个参数是页面的右边界。

首页

this.state.pageIndex * this.state.pageSize, // 0 * 5 = 0
this.state.pageIndex * this.state.pageSize + this.state.pageSize // 0 * 5 + 5 = 5

显示从索引 0 到 5 的元素。

第二页

this.state.pageIndex * this.state.pageSize, // 1 * 5 = 5
this.state.pageIndex * this.state.pageSize + this.state.pageSize // 1 * 5 + 5 = 10

显示从索引 5 到 10 的元素。

...
  render() {
    return (
      <>
        <button onClick={event => this.handlePrevPageClick(event)}>
          Prev page
        </button>
        <button onClick={event => this.handleNextPageClick(event)}>
          Next page
        </button>
        <table border="1">
          <thead>
            <tr>
              <th>Id</th>
              <th>Name</th>
            </tr>
          </thead>
          <tbody>
            {this.state.items
              .slice(
                this.state.pageIndex * this.state.pageSize,
                this.state.pageIndex * this.state.pageSize + this.state.pageSize
              )
              .map(item => (
                <tr>
                  <td>{item.id}</td>
                  <td>{item.name}</td>
                </tr>
              ))}
          </tbody>
        </table>
      </>
    );
  }
}

如果您想查看完整的工作示例,请使用此CodeSandbox 链接

【讨论】:

  • 仅链接答案在这里不是很有用。您能否在此处粘贴代码的重要部分和/或解释其工作原理?
  • @Brandon 是的,当然。
  • 你能显示中间的页数吗? 1234
【解决方案2】:

您需要根据记录数动态生成分页按钮,然后在按下分页按钮时,设置页码并创建一个数组,如果您想根据页码和每页大小显示项目。

这是示例代码,可让您了解如何完成此操作。这不是完整的或错误的证明,因为这是您的工作。我希望能得到这个想法。

class CustomerDebt extends Component {
  constructor(props) {
    super(props);

    this.domain = `http://127.0.0.1:8000`;
    this.state = {
      isLoaded: true,

      items: [], //Customer Debt Items,
      pageItems: [],
      page: 0,
      pageSize: 6
    };
  }

  async componentDidMount() {
    const { pageSize } = this.state;
    //customer debt list
    await fetch(
      `${this.domain}/api/debt/list?customer=` +
        this.props.customerInfo.customer.id,
      {
        headers: {
          Authorization: `Bearer ${localStorage.getItem("token")}`,
          "Content-Type": "application/json"
        }
      }
    )
      .then(res => {
        if (res.ok) {
          return res.json();
        } else {
          return res.json().then(err => Promise.reject(err));
        }
      })
      .then(json => {
        this.setState({
          items: json,
          pageItems: json.slice(0, pageSize)
        });
        this.abortController.abort();
      })
      .catch(error => {
      return error;
      });
  }

  render() {
    const { isLoaded, pageItems, items, page, pageSize } = this.state;
    const pages = Math.ceil(items.length / page);
    const paginationItems = Array(pages).fill('').map((i, index) => (
    <PaginationItem active={page === index}>
      <PaginationLink tag="button" onClick={() => this.setState({page: index })}}>2</PaginationLink>
     </PaginationItem>
    ));
    if (!isLoaded) {
      return <div>Loading...</div>;
    } else {
      return (
        <div className={"animated fadeIn container-fluid"}>
          <Row>
            <Col>
              <Card>
                <CardHeader>
                  <i className="fa fa-align-justify" /> Müşteri Borcu
                </CardHeader>
                <CardBody>
                  <Table hover bordered striped responsive size="sm">
                    <thead>
                      <tr>
                        <th width={"10"} />
                        <th width={"15"}>No</th>
                        <th style={{ display: "none" }}>User</th>
                        <th style={{ display: "none" }}>Key</th>
                        <th style={{ display: "none" }}>CreatedUserKey</th>
                        <th width={"40"}>Total debt</th>
                        <th width={"40"}>Received amount</th>
                        <th scope={"row"}>Description</th>
                        <th width={"20"}>Payment Date</th>
                      </tr>
                    </thead>
                    <tbody>
                      {pageItems.map(item => {
                        return (
                          <tr key={item.id}>
                            <td>{item.id}</td>
                            <td style={{ display: "none" }}>{item.user}</td>
                            <td style={{ display: "none" }}>{item.debtKey}</td>
                            <td style={{ display: "none" }}> {" "} {item.createduserKey}{" "} </td>
                            <td>{item.totalDebt}</td>
                            <td>{item.receivedAmount}</td>
                            <td>{item.description}</td>
                            <td> {new Date(item.paymentDate).toLocaleString()} </td>
                          </tr>
                        );
                      })}
                    </tbody>
                  </Table>
                  <nav>
                    <Pagination>
                      <PaginationItem onClick={() => this.setState(prev => ({page: prev.page -1}))}>
                        <PaginationLink>
                          Back
                        </PaginationLink>
                      <PaginationItem onClick={() => this.setState(prev => ({page: prev.page + 1}))}>
                        <PaginationLink next tag="button">
                          Next
                        </PaginationLink>
                      </PaginationItem>
                      <PaginationItem></PaginationItem>
                    </Pagination>
                  </nav>
                </CardBody>
              </Card>
            </Col>
          </Row>
        </div>
      );
    }
  }
}
export default CustomerDebt;

【讨论】:

  • 您的代码非常好,伙计。但是“RangeError:无效的数组长度”错误。代码 sn-p: const paginationItems = Array (pages) .fill ('')。地图 ((i, 索引) => (
  • 错误:{ "message": "Uncaught SyntaxError: Unexpected token 'stacksnippets.net/js", "lineno": 63, "colno": 5 }跨度>
猜你喜欢
  • 1970-01-01
  • 2019-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-13
  • 2019-12-27
  • 1970-01-01
  • 2020-12-31
相关资源
最近更新 更多