我正在尝试使用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帮助解决相同问题。也欢迎对代码进行任何改进。
答案 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)
此方法存在多个问题:
this.handleClick
必须从父级传入。
setState
函数是异步的。因此,在设置状态后立即访问状态可能不会导致您想要的状态。为了解决这个问题,React提供了一个回调函数作为第二个参数。仅在状态运行后才运行。
分页更改后,您没有更新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();
});
};