从react-js-pagination获取paginator到页面上显示

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从react-js-pagination获取paginator到页面上显示相关的知识,希望对你有一定的参考价值。

我有一个反应应用程序,它是购物网站的前端。

我有一个产品页面,我试图将react-js-pagination的分页添加到它的底部,这样我就不必一次呈现整个产品列表。

我已经遵循了从https://www.npmjs.com/package/react-js-pagination实施分页的指导原则,但我仍然无法显示它(页面的其余部分正确显示)。

谁能明白为什么?

请参阅下面整个页面的代码:

import React from 'react';
import Pagination from 'react-js-pagination';
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';

import changeBrandFilter from '../actions/changeBrandFilter';
import changePriceFilter from '../actions/changePriceFilter';

import CategoryOverview from './CategoryOverview';
import Filter from './Filter';
import ProductsListItem from './ProductsListItem';
import ProductsPageContainerCSS from './ProductsPageContainer.css';

class ProductsPage extends React.Component{
    createCategoryOverview() {
        return this.props.overview.map(overview => {
            return (
                <CategoryOverview 
                    title={overview.title}
                    text={overview.text}
                    image={overview.imageSource}
                    alt={overview.imageAlt}
                />
            )
        })
    }
    createBrandFilterList() {
        return this.props.brandFilters.map(filter => {
            return (
                <Filter
                    key={filter.brand}
                    id={filter.brand}
                    changeFilter={() => this.props.changeBrandFilter(filter)}
                    inuse={filter.inuse}
                    disabled={filter.disabled}
                />
            )
        })
    }
    createPriceRangeFilterList() {
        return this.props.priceRangeFilters.map(filter => {
            return (
                <Filter
                    key={filter.priceRange}
                    id={filter.priceRange}
                    changeFilter={() => this.props.changePriceFilter(filter)}
                    inuse={filter.inuse}
                    disabled={filter.disabled}
                />
            )
        })
    }
    filterDivExtenionToggle () {
            var filterDivExtension = document.querySelector('.filterDivExtension');
            var chevronUp = document.querySelector('#chevronUp');
            var chevronDown = document.querySelector('#chevronDown');
            var icon;
            if (filterDivExtension.style.display === 'block') {
                filterDivExtension.style.display = 'none';
                chevronUp.style.display = 'none';
                chevronDown.style.display = 'block';
            } else {
                filterDivExtension.style.display = 'block';
                chevronUp.style.display = 'block';
                chevronDown.style.display = 'none';
            }
    }
    createProductsList() {
        if(this.props.products.length > 0) {
            return this.props.products.map(product =>{
                if (this.props.products.indexOf(product) >= this.state.activePage -1 && this.props.products.indexOf(product) < (this.state.activePage*12)) {
                    return (
                        <ProductsListItem
                            key={product.id}
                            brand={product.brand}
                            model={product.model}
                            price={product.price}
                            image={product.image}
                            link={"/"+this.props.match.params.type+"/"+product.id}
                        />
                    )
                }

            })} else {
                return <div>No products match the filter criteria selected above.</div>
            } 
    }
    constructor(props) {
        super(props);
        this.state = {activePage: 1};
    }
    handlePageChange(pageNumber) {
        this.setState({activePage: pageNumber});
    }
    render () {
        return (
            <div>
                <div className="container">
                    {this.createCategoryOverview()}
                    <div ClassName="row">
                        <div className= "filterDiv col-12">
                            <div className="iconCrossbar">
                                <i id="chevronDown" className="fa fa-chevron-down" onClick={this.filterDivExtenionToggle}></i>
                                <i id="chevronUp" className="fa fa-chevron-up" onClick={this.filterDivExtenionToggle}></i>
                            </div>
                            <div className="filterDivExtension">
                                <div className="row">
                                    <div className="filtersList col-md-6 col-12">
                                        Filter by Brand:
                                        <div>
                                            {this.createBrandFilterList()}
                                        </div>
                                    </div>
                                    <div className="filtersList col-md-6 col-12">
                                        Filter by Price Range:
                                        <div>
                                            {this.createPriceRangeFilterList()}
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                    <div className="row productsList">
                        {this.createProductsList()}
                    </div>
                </div>
                <Pagination 
                    activePage={this.state.activePage}
                    itemsCountPerPage={12}
                    totalItemsCount={this.props.products.length}
                    pageRangeDisplayed={2}
                    onChange={this.handlePageChange}
                />
            </div>
        )
    }
};

function mapStateToProps(state , ownProps) {
    let brandFilters = state.brandFilters;
    let filtered_brandFilters = brandFilters;
    filtered_brandFilters = filtered_brandFilters.filter(
        filter => filter.type === ownProps.match.params.type
    )
    let priceRangeFilters = state.priceRangeFilters;
    let filtered_priceRangeFilters = priceRangeFilters;
    filtered_priceRangeFilters = filtered_priceRangeFilters.filter(
        filter => filter.type === ownProps.match.params.type
    )
    let products = state.products;
    let overviews = state.overviews;
    let overview = overviews.filter(
        overview => overview.type === ownProps.match.params.type
    )
    let filtered_products = products;
    filtered_products = filtered_products.filter(
        product => product.type === ownProps.match.params.type //gets type from the the route params and finds products which have type that matches
    )
    let activeBrandFilters = brandFilters.filter(
        item => item.inuse === true
    );
    activeBrandFilters.forEach(filter => {
        filtered_products = filtered_products.filter(
            product => product.brand === filter.brand
        )
    });
    let activePriceRangeFilters = priceRangeFilters.filter(
        item => item.inuse === true
    );
    activePriceRangeFilters.forEach(filter => {
        filtered_products = filtered_products.filter(
            product => product.priceRange === filter.priceRange
        );
    });
    return {
        overview: overview,
        brandFilters: filtered_brandFilters,
        priceRangeFilters: filtered_priceRangeFilters,
        products: filtered_products
    };
};

function matchDispatchToProps(dispatch){
    return bindActionCreators({changeBrandFilter: changeBrandFilter, changePriceFilter: changePriceFilter}, dispatch);
};

export const ProductsPageContainer = connect(mapStateToProps, matchDispatchToProps)(ProductsPage);

任何帮助将不胜感激。

谢谢。

答案

好的,如果您阅读我对Leonel的回答的评论,您会看到我确实设法让react-js-paginator的paginator显示但仍然无法使其工作。

我改为制作了自己的自定义基本分页器组件。

请找到我在下面创建的paginator组件:

import React from 'react';

class Paginaton extends React.Component {
    render () {
        return (
            <div className="row">
                <div className="pagination">
                    <button id="prevPage" className="btn" disabled={this.props.disabled1} onClick={() => this.props.onclick1()}>prev</button>
                    <button id="nextPage" className="btn" disabled={this.props.disabled2} onClick={() => this.props.onclick2()}>next</button>
                </div>
            </div>
        )
    }
}

export default Paginaton;

如您所见,这只是一个上一个按钮和一个下一个按钮。

然后,在容器组件中,确保只有需要处于活动状态的按钮显示为活动状态,而不需要处于活动状态的按钮显示为非活动状态。这确保了在产品的第一页上prev不是可点击的选项,而在产品的最后一页上,next不是可点击的选项。

我还确保为组件添加一个“键”支柱,该组件对于显示该组件的路径是唯一的。这是必要的,因为我的分页依赖于我在组件中设置的状态,该状态声明了'activePage',这样当我进入另一种类型的产品页面时(例如从套件产品到坦克产品),组件将重新安装(因为两个路由呈现相同的组件,呈现的产品由路由参数决定),状态将恢复到其初始状态({activePage:1})。

请参阅下面的容器组件:

import React from 'react';
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';

import changeBrandFilter from '../actions/changeBrandFilter';
import changePriceFilter from '../actions/changePriceFilter';

import CategoryOverview from './CategoryOverview';
import Filter from './Filter';
import ProductsListItem from './ProductsListItem';
import ProductsPageContainerCSS from './ProductsPageContainer.css';
import Pagination from './Pagination';

class ProductsPage extends React.Component{
    createCategoryOverview() {
        let i = 1;
        return this.props.overview.map(overview => {
            i++
            return (
                <CategoryOverview 
                    key={"catOverview"+i} //each child in an array or iterator should have a unique "key" prop
                    title={overview.title}
                    text={overview.text}
                    image={overview.imageSource}
                    alt={overview.imageAlt}
                />
            )
        })
    }
    createBrandFilterList() {
        let i = 1;
        return this.props.brandFilters.map(filter => {
            i++
            return (
                <Filter
                    key={filter.brand+i+"brand"}
                    name={this.props.match.params.type + "brandFilter"} //so that each seperate group of radio buttons (filters) refer only to each other. (the name is shared within each group)
                    id={filter.brand}
                    changeFilterResetPageNumber={() => {this.props.changeBrandFilter(filter); this.handlePageChange(1)}} //without page reset would often get no products displayed on filter application due to the activePage state remaining at the page that was active at the time of filter application
                    inuse={filter.inuse}
                />
            )
        })
    }
    createPriceRangeFilterList() {
        let i = 1;
        return this.props.priceRangeFilters.map(filter => {
            i++
            return (
                <Filter
                    key={filter.priceRange+i+"priceRange"}
                    name={this.props.match.params.type + "priceFilter"} 
                    id={filter.priceRange}
                    changeFilterResetPageNumber={() => {this.props.changePriceFilter(filter); this.handlePageChange(1)}}
                    inuse={filter.inuse}
                />
            )
        })
    }
    filterDivExtenionToggle () {
            var filterDivExtension = document.querySelector('.filterDivExtension');
            var chevronUp = document.querySelector('#chevronUp');
            var chevronDown = document.querySelector('#chevronDown');
            var icon;
            if (filterDivExtension.style.display === 'block') {
                filterDivExtension.style.display = 'none';
                chevronUp.style.display = 'none';
                chevronDown.style.display = 'block';
            } else {
                filterDivExtension.style.display = 'block';
                chevronUp.style.display = 'block';
                chevronDown.style.display = 'none';
            }
    }
    createProductsList() {
        if(this.props.products.length > 0) {
            return this.props.products.map(product =>{
                if (this.props.products.indexOf(product) >= (this.state.activePage*12) - 12 && this.props.products.indexOf(product) < (this.state.activePage*12)) { //render the 12 (number of products per page) products that correspond to the current (active) page
                    return (
                        <ProductsListItem
                            key={product.id}
                            brand={product.brand}
                            model={product.model}
                            price={product.price}
                            image={product.image}
                            link={"/"+this.props.match.params.type+"/"+product.id}
                        />
                    )
                }

            })} else {
                return <div>No products match the filter criteria selected above.</div>
            } 
    }
    state = {
        activePage: 1
    }
    handlePageChange(pageNumber) {
        this.setState({activePage: pageNumber});
    }
    createPagination() {
        if (this.props.products.length > 12) {
            if (this.props.products.length > this.state.activePage * 12 && this.state.activePage > 1) { //if there are products following AND preceding the current page
                return (
                    <Pagination 
                        onclick1={() => this.handlePageChange(this.state.activePage - 1)}
                        onclick2={() => this.handlePageChange(this.state.activePage + 1)}
                        disabled1={false}
                        disabled2={false}
                    />
                )
            } else if (this.props.products.length > this.state.activePage * 12) { //if there are only products following the current page
                return (
                    <Pagination 
                        onclick1={() => this.handlePageChange(this.state.activePage - 1)}
                        onclick2={() => this.handlePageChange(this.state.activePage + 1)}
                        disabled1={true}
                        disabled2={false}
                    />
                ) 
            } else if (this.state.activePage > 1) { //if there are only products preceding the current page
                return (
                    <Pagination 
                        onclick1={() => this.handlePageChange(this.state.activePage - 1)}
                        onclick2={() => this.handlePageChange(this.state.activePage + 1)}
                        disabled1={false}
                        disabled2={true}
                    />
                ) 
            }

        }
    }
    render () {
        return (
            <div>
                <div className="container">
                    {this.createCategoryOverview()}
                    <div className="row">
                        <div className= "filterDiv col-12">
                            <div className="iconCrossbar">
                                <i id="chevronDown" className="fa fa-chevron-down" onClick={this.filterDivExtenionToggle}></i>
                                <i id="chevronUp" className="fa fa-chevron-up" onClick={this.filterDivExtenionToggle}></i>
                            </div>
                            <div className="filterDivExtension">
                                <div className="row">
                                    <div className="filtersList col-md-6 col-12"

以上是关于从react-js-pagination获取paginator到页面上显示的主要内容,如果未能解决你的问题,请参考以下文章

从解码渲染层面对比 PAG 与 lottie

从 AE 制作到落地开发,腾讯推出移动端动画组件PAG,释放设计生产力

web端腾讯PAG初体验

腾讯自主研发动画组件PAG开源

对话腾讯陈仁健:聊一聊腾讯PAG动效解决方案的生产能力与开源情况

对话腾讯陈仁健:聊一聊腾讯PAG动效解决方案的生产能力与开源情况