loading...
Cover image for Day 25 of #100DaysOfCode: Apply Pagination for React Components with Redux

Day 25 of #100DaysOfCode: Apply Pagination for React Components with Redux

jenhsuan profile image Sean Hsieh ・3 min read

Introduction

This article introduces using react-paginate with Redux.

Preparations

1.Redux

2.Install package

npm install -S react-paginate

Edit Roles in Redux

  • We need to add partial articles, per page, page count, offset in Redux

1.Types

export const SET_PARTIAL_ARTICLES = 'SET_PARTIAL_ARTICLES';
export const SET_PERPAGE = 'SET_PERPAGE';
export const SET_PAPE_COUNT = 'SET_PAPE_COUNT';
export const SET_OFFSET = 'SET_OFFSET';

2.Actions

import { 
    SET_PARTIAL_ARTICLES,
    SET_PERPAGE,
    SET_PAPE_COUNT,
    SET_OFFSET
} from '../types'

export interface SetPartialArticlesAction {
    readonly type: typeof SET_PARTIAL_ARTICLES
    readonly payload: string
}

export interface SetPerpageAction {
    readonly type: typeof SET_PERPAGE
    readonly payload: number
}

export interface SetPageCountAction {
    readonly type: typeof SET_PAPE_COUNT
    readonly payload: number
}

export interface SetOffsetAction {
    readonly type: typeof SET_OFFSET
    readonly payload: number
}

export const setPartialArticles = articles => dispatch => {
    dispatch({
        type: SET_PARTIAL_ARTICLES, 
        payload: articles})
}

export const setLoading = isLoading => dispatch => {
    dispatch({
        type: SET_LOADING, 
        payload: isLoading})
}

export const setOffset = offset => dispatch => {
    dispatch({
        type: SET_OFFSET, 
        payload: offset})
}

export const setPageCount = pageCount => dispatch => {
    dispatch({
        type: SET_PAPE_COUNT, 
        payload: pageCount})
}

3.Reducer

import { 
    SET_PARTIAL_ARTICLES,
    SET_PERPAGE,
    SET_PAPE_COUNT,
    SET_OFFSET
} from '../types'

 //Initial state
 interface ArticlesState {
     partialArticles: Array<ArticleType>;
     perpage: number;
     pageCount: number;
     offset: number;
 }

 const initialState = {
     partialArticles: [],
     perpage: 10,
     pageCount: 1,
     offset: 0
 }

//Selector functions
export const selectPartialArticlesState = (rootState: RootState) => rootState.articlesReducer.partialArticles;
export const selectPerpageState = (rootState: RootState) => rootState.articlesReducer.perpage;
export const selectPageCountState = (rootState: RootState) => rootState.articlesReducer.pageCount;
export const selectOffsetState = (rootState: RootState) => rootState.articlesReducer.offset;

 //Reducer
 const articlesReducer = (state: ArticlesState = initialState,
action: SetPartialArticlesAction | SetOffsetAction | SetPerpageAction | SetPageCountAction ) => {
        case SET_PARTIAL_ARTICLES:
            return {
                ...state,
                isLoading: false,
                partialArticles: action.payload
        case SET_OFFSET:
            return {
                ...state,
                offset: action.payload
            }
        case SET_PAPE_COUNT:
            return {
                ...state,
                pageCount: action.payload
            }
        case SET_PERPAGE:
            return {
                ...state,
                perpage: action.payload
            }
        default:
            return state; 
      }
}


4.Store

5.Provider and the parent component

6. The child component and useSelect, useDispatch

  • Suppose that we already have objects in articles state
import React, {useEffect, Fragment, useState} from 'react'
import { useDispatch, useSelector } from 'react-redux';
import ReactPaginate from 'react-paginate';
import {
     selectPartialArticlesState,
     selectArticlesState,
     selectOffsetState,
     selectPageCountState,
     selectPerpageState
 } from './reducers/articlesReducer';

 import { 
     setPartialArticles,
     setOffset,
     setPageCount
 } from './actions/articlesAction';

const Menu = () => {
     const disPatch = useDispatch();
     const articles = useSelector(selectProducts);
     const articles = useSelector(selectArticlesState);
     const partialArticles = useSelector(selectPartialArticlesState);
     const perpage = useSelector(selectPerpageState);
     const pageCount = useSelector(selectPageCountState);
     const offset = useSelector(selectOffsetState);

    useEffect(()=> { 
        var count = Math.ceil(articles.length / perpage);
        disPatch(setPageCount(count));
        setPartialData();
    }, [offset])

    const setPartialData = () =>  {
        const partialData = articles.slice(offset, offset + perpage);
        disPatch(setPartialArticles(partialData));
    }

    const handlePageSlected = e => {
        disPatch(setOffset(e.selected * perpage));
    }

   return (
        <Fragment>
            {articles.map(article=> <Article article = {article}/>)}
                <div >
                    <ReactPaginate
                     previousLabel={"prev"}
                     nextLabel={"next"}
                     breakLabel={"..."}
                     breakClassName={"break-me"}
                     pageCount={pageCount}
                     marginPagesDisplayed={2}
                     pageRangeDisplayed={5}
                     onPageChange={handlePageSlected}
                     containerClassName={"pagination"}
                     subContainerClassName={"pages pagination"}
                     activeClassName={"active"}/>
                </div>
        </Fragment>
    )
}

About me

There are some of my articles. Feel free to check if you like!

Posted on by:

jenhsuan profile

Sean Hsieh

@jenhsuan

5+ year work experience in the software engineering field. Near 2-year work experience with front-end JavaScript framework like React.js, Knockout.js. and Microsoft solution.

Discussion

markdown guide