如何使用 react-table 和 react-paginate 组件实现纯客户端分页而不向服务器发出请求?
How to implement pure client side pagination without requests to the server in react, using react-table and react-paginate components?
我在 componentDidMount 方法中使用来自服务器的对象数组,然后将其保存到状态中。
如果我从 select 组件更改页面大小,一切正常,但页码点击不起作用。
例如,我将页面大小设置为 20。我的数据数组长度等于 29,所以我有 2 页。在反应 table 中,有 20 行,并且 selected 页 - 第 1 页。当我 select 第 2 页时,没有任何反应。它应该显示剩余的 9 行,但什么也没有发生。
我知道一般情况下页面大小对应的数据量一定是在点击跳转页面时来自服务器的。但是我得到的任务是我应该在不向服务器发出请求的情况下实现所有内容。
我该如何实现?您的任何帮助都会很有用,在此先感谢您!这是我的代码:
constructor:
perPage: JSON.parse(localStorage.getItem('detailsTablePerPageOrderEdit')) || 20,
pageRanges: [20, 50, 100, 200, 300, 500, 1000],
<CustomReactTable
columns={columnsDetails}
tableHeight={_.isEmpty(this.state.details) ? '25vh' : '80%'}
data={this.state.details}
onTrClick={(data) => this.handleDetailSelect(data)}
pageSize={this.state.perPage}
/>
<PaginationRow
changePerPage={(pageSize) => this.onPageSizeChange(pageSize)}
count={this.state.details.length}
handlePageChange={(page) => this.handlePageChange(page)}
page={this.state.page}
perPage={this.state.perPage}
pageRanges={this.state.pageRanges}
/>
handlePageChange = (page) => {
this.setState({ page: page.selected + 1 });
//I think, here should be some code to implement pagination
};
onPageSizeChange = pageSize => {
console.log(typeof pageSize);
localStorage.setItem('detailsTablePerPageOrderEdit', pageSize);
this.setState({
page: 1,
perPage: pageSize
});
};
paginationRow 组件:
import React from 'react';
import {Row, Col} from 'react-bootstrap';
import ReactPaginate from 'react-paginate';
import PaginationCount from './PaginationCount';
import i18n from '../../i18n';
export default (props) => {
if(props.count <= 0 || props.page < 0 || props.perPage < 0){
return null;
}
const fromItem = (props.page - 1) * props.perPage + 1;
let toItem = props.page * props.perPage;
toItem = toItem > props.count ? props.count : toItem;
const handlePageSizeChange = e => {
props.changePerPage && props.changePerPage(e.target.value);
};
const pageRanges = props.pageRanges || [50, 100, 200, 300, 500, 1000];
return(
<Row>
<div className="col padded">
<ReactPaginate
activeClassName="active"
breakLabel={<a href="#!">...</a>}
containerClassName="pagination"
disableInitialCallback
forcePage={props.page - 1}
initialPage={props.page - 1}
marginPagesDisplayed={5}
nextLabel={i18n.t('PaginationRow.next_label')}
onPageChange={props.handlePageChange}
pageCount={props.count/props.perPage}
pageRangeDisplayed={5}
previousLabel={i18n.t('PaginationRow.previous_label')}
subContainerClassName="pages pagination"
/>
</div>
{props.perPage ?
<div className="col col-md-auto ">
<div className="form-group">
<select
className="form-control paginationSelect" id="exampleFormControlSelect1"
name="perPage"
onChange={handlePageSizeChange}
value={props.perPage}
>
{pageRanges.map(r => (<option key={r} value={r}>{r}</option>))}
</select>
</div>
</div> : null
}
<div className="col text-nowrap">
<div className="paginationTextInfo">
<PaginationCount
itemFrom={fromItem}
itemTo={toItem}
totalCount={props.count}
/>
</div>
</div>
</Row>
);
};
看来您必须根据页面状态(当前分页页面)修改结果数组。
与 F.E array.slice 函数:
function paginate (array, page_size, page_number) {
return array.slice((page_number-1) * page_size, (page_number) * page_size);
}
我在 componentDidMount 方法中使用来自服务器的对象数组,然后将其保存到状态中。
如果我从 select 组件更改页面大小,一切正常,但页码点击不起作用。
例如,我将页面大小设置为 20。我的数据数组长度等于 29,所以我有 2 页。在反应 table 中,有 20 行,并且 selected 页 - 第 1 页。当我 select 第 2 页时,没有任何反应。它应该显示剩余的 9 行,但什么也没有发生。
我知道一般情况下页面大小对应的数据量一定是在点击跳转页面时来自服务器的。但是我得到的任务是我应该在不向服务器发出请求的情况下实现所有内容。
我该如何实现?您的任何帮助都会很有用,在此先感谢您!这是我的代码:
constructor:
perPage: JSON.parse(localStorage.getItem('detailsTablePerPageOrderEdit')) || 20,
pageRanges: [20, 50, 100, 200, 300, 500, 1000],
<CustomReactTable
columns={columnsDetails}
tableHeight={_.isEmpty(this.state.details) ? '25vh' : '80%'}
data={this.state.details}
onTrClick={(data) => this.handleDetailSelect(data)}
pageSize={this.state.perPage}
/>
<PaginationRow
changePerPage={(pageSize) => this.onPageSizeChange(pageSize)}
count={this.state.details.length}
handlePageChange={(page) => this.handlePageChange(page)}
page={this.state.page}
perPage={this.state.perPage}
pageRanges={this.state.pageRanges}
/>
handlePageChange = (page) => {
this.setState({ page: page.selected + 1 });
//I think, here should be some code to implement pagination
};
onPageSizeChange = pageSize => {
console.log(typeof pageSize);
localStorage.setItem('detailsTablePerPageOrderEdit', pageSize);
this.setState({
page: 1,
perPage: pageSize
});
};
paginationRow 组件:
import React from 'react';
import {Row, Col} from 'react-bootstrap';
import ReactPaginate from 'react-paginate';
import PaginationCount from './PaginationCount';
import i18n from '../../i18n';
export default (props) => {
if(props.count <= 0 || props.page < 0 || props.perPage < 0){
return null;
}
const fromItem = (props.page - 1) * props.perPage + 1;
let toItem = props.page * props.perPage;
toItem = toItem > props.count ? props.count : toItem;
const handlePageSizeChange = e => {
props.changePerPage && props.changePerPage(e.target.value);
};
const pageRanges = props.pageRanges || [50, 100, 200, 300, 500, 1000];
return(
<Row>
<div className="col padded">
<ReactPaginate
activeClassName="active"
breakLabel={<a href="#!">...</a>}
containerClassName="pagination"
disableInitialCallback
forcePage={props.page - 1}
initialPage={props.page - 1}
marginPagesDisplayed={5}
nextLabel={i18n.t('PaginationRow.next_label')}
onPageChange={props.handlePageChange}
pageCount={props.count/props.perPage}
pageRangeDisplayed={5}
previousLabel={i18n.t('PaginationRow.previous_label')}
subContainerClassName="pages pagination"
/>
</div>
{props.perPage ?
<div className="col col-md-auto ">
<div className="form-group">
<select
className="form-control paginationSelect" id="exampleFormControlSelect1"
name="perPage"
onChange={handlePageSizeChange}
value={props.perPage}
>
{pageRanges.map(r => (<option key={r} value={r}>{r}</option>))}
</select>
</div>
</div> : null
}
<div className="col text-nowrap">
<div className="paginationTextInfo">
<PaginationCount
itemFrom={fromItem}
itemTo={toItem}
totalCount={props.count}
/>
</div>
</div>
</Row>
);
};
看来您必须根据页面状态(当前分页页面)修改结果数组。
与 F.E array.slice 函数:
function paginate (array, page_size, page_number) {
return array.slice((page_number-1) * page_size, (page_number) * page_size);
}