Day 25 of #100DaysOfCode: Apply Pagination for React Components with Redux
Tags: 100daysofcode, react, redux, javascript
Published: 2020-05-31 03:45:52

## Introduction
This article introduces using *react-paginate* with *Redux*. 

##Preparations
1.Redux
* [Day 14 of #100DaysOfCode: Redux (use useSelect and useDispatch instead of connect)](https://dev.to/jenhsuan/day-14-of-100daysofcode-redux-use-useselect-and-usedispatch-instead-of-connect-3cmc)
* [Day 15 of #100DaysOfCode: TypeScript + CRA + Redux (use useSelect and useDispatch instead of connect)](https://dev.to/jenhsuan/day-15-of-100daysofcode-typescript-redux-use-useselect-and-usedispatch-instead-of-connect-4plh)

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
```javascript
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

```javascript
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

```javascript
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
* As same as [Day 14](https://dev.to/jenhsuan/day-14-of-100daysofcode-redux-use-useselect-and-usedispatch-instead-of-connect-3cmc)

####5.Provider and the parent component
* As same as [Day 14](https://dev.to/jenhsuan/day-14-of-100daysofcode-redux-use-useselect-and-usedispatch-instead-of-connect-3cmc)

####6. The child component and useSelect, useDispatch
* Suppose that we already have objects in articles state

```javascript
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! 
* My blog-posts for software developing: https://medium.com/a-layman
* My web resume: https://jenhsuan.github.io/ALayman/cover.html
* Facebook page: https://www.facebook.com/imalayman