可重复使用的反应分页组件

时间:2019-11-17 12:52:12

标签: javascript reactjs pagination

我正在尝试使用reactstrap作为UI库创建动态分页react组件。我被困在完成相同的问题上。

UsersCard.js

import React, { Component } from 'react'
import axios from 'axios';
import PaginationTable from './PaginationTable';



    export default class UsersCard extends Component {

        constructor(props) {
          super(props)

          this.state = {
              usersData: [],
              loading: false,
              per_page: 3,
              current_page: 1,
              total_data: '',
              currentPosts: []
          }
        }

    async componentDidMount(){
      await axios.get('https://reqres.in/api/users')
        .then(res => {
            this.setState({
              usersData: res.data.data,
              loading: false,
              total_data: res.data.data.length
            })
        })
        .catch(err => console.log(err));

        const indexOfLastPost = this.state.current_page * this.state.per_page;
        const indexOfFirstPage = indexOfLastPost - this.state.per_page;

        const currentPosts = this.state.usersData.slice(indexOfFirstPage, indexOfLastPost);

        this.setState({ currentPosts })

    }

    handleClick = (number) => {
      this.setState({
        current_page: number
      })
    }

      render() {
        const { per_page, handleClick, total_data, current_page, currentPosts } = this.state;

        return (
          <div>
            <table>
                <thead>
                    <tr>
                        <th>Id</th>
                        <th>First Name</th>
                        <th>email</th>
                        <th>Last Name</th>
                    </tr>
                </thead>
                {currentPosts.map(x => {
                return(
                        <React.Fragment key={x.id}>
                                <tbody>
                                    <tr>
                                        <td>{x.id}</td>
                                        <td>{x.first_name}</td>
                                        <td>{x.email}</td>
                                        <td>{x.last_name}</td>
                                    </tr>
                                </tbody>
                        </React.Fragment>
                        )
                })}
            </table>
            <PaginationTable
                      per_page={per_page}
                      current_page={current_page}
                      total_data={total_data}
                      handleClick={handleClick}
                    />
          </div>
        )
      }
    }

PaginationTable.js

import React from 'react';
import { Pagination, PaginationItem, PaginationLink } from 'reactstrap';

const PaginationTable = ({ per_page, total_data, handleClick, current_page }) => {

    let pageNumbers = [];

    for(let i=1; i<= Math.ceil(total_data/per_page); i++)
    {   
        pageNumbers.push(
        <PaginationItem key={i} active={current_page === i ? true : false}>
            <PaginationLink onClick={() => handleClick(i)} href="#">
                {i}
            </PaginationLink>
        </PaginationItem>)
    }



    return(
            <Pagination aria-label="Page navigation example">
                <PaginationItem disabled={current_page <= 1}>
                    <PaginationLink onClick={()=>handleClick(current_page-1)}
                            previous 
                            href="#" 
                    />
                    </PaginationItem>

                        {pageNumbers}

                <PaginationItem disabled={current_page >= per_page - 1}>
                    <PaginationLink onClick={()=>handleClick(current_page + 1)}
                            next 
                            href="#" 
                    />
                </PaginationItem>
            </Pagination>

    )

}

导出默认的PaginationTable;

我的问题是这样的:

1)Reactstrap分页用户界面显示不正确。

2)每当我单击next按钮时,它都会显示错误:TypeError: handleClick is not a function

我对动态分页概念有些陌生,无法识别遇到的错误。 Kindlt帮助解决相同问题。也欢迎对代码进行任何改进。

2 个答案:

答案 0 :(得分:1)

关于第一个。您正在尝试仅渲染pageNumbers中的jsx元素数组。取而代之的是,您只需将数字推入该数组即可:

let pageNumbers = [];

for(let i=1; i<= Math.ceil(total_data/per_page); i++)
{   
  pageNumbers.push(i)
}

,然后在应使用地图的位置直接渲染分页项。

{pageNumbers.map(i => (
  <PaginationItem key={i} active={current_page === i ? true : false}>
      <PaginationLink onClick={() => handleClick(i)} href="#">
         {i}
      </PaginationLink>
   </PaginationItem>
))}

关于第二个问题:handleClick不是函数,因为您首先要在render函数上方定义它,然后在破坏状态时将其覆盖,但是您的目录中没有handleClick这样的东西状态,因此将其分配为null或undefined。 您要做的就是在解构分配中将其删除,并将其作为this.handleClick传递,它应该可以工作。

答案 1 :(得分:1)

此方法存在多个问题:

  1. this.handleClick必须从父级传入。

  2. setState函数是异步的。因此,在设置状态后立即访问状态可能不会导致您想要的状态。为了解决这个问题,React提供了一个回调函数作为第二个参数。仅在状态运行后才运行。

  3. 分页更改后,您没有更新currentPosts状态。分页组件仅与更改页码有关,数据更改必须手动处理。您可以使用以下方法处理此问题:

  async componentDidMount() {
    await axios
      .get("https://reqres.in/api/users")
      .then(res => {
        this.setState({
          usersData: res.data.data,
          loading: false,
          total_data: res.data.data.length
        }, () => {
          this.formatData();
        });
      })
      .catch(err => console.log(err));
  }

  formatData() {
    const indexOfLastPost = this.state.current_page * this.state.per_page;
    const indexOfFirstPage = indexOfLastPost - this.state.per_page;

    const currentPosts = this.state.usersData.slice(
      indexOfFirstPage,
      indexOfLastPost
    );

    this.setState({ currentPosts });
  }

  handleClick = number => {
    this.setState({
      current_page: number
    }, () => {
      this.formatData();
    });
  };

Updated Stackblitz