• 2021-09-14

    Reactのページネーション実装

    import React, { FC, useState, useRef, useEffect } from ‘react’
    import styles from ‘./Pagination.module.css’
    import classNames from ‘classnames’
    interface Props {
    first: number
    total: number
    current?: number
    onChange: (e: { page: number }) =>void
    }
    const Pagination: FC<Props> = ({ first, total, current = 1, onChange }) => {
    constisFirstRender = useRef(true)
    const [currentPage, setCurrentPage] = useState(current)
    // ページングした後に絞り込みするとページングのstateが戻らない
    useEffect(() => {
    setCurrentPage(current)
    }, [current]);
    useEffect(() => {
    if (isFirstRender.current) {
    isFirstRender.current = false
    return
    }
    onChange({ page:currentPage })
    }, [currentPage])
    consttotalPage: number = Math.ceil(total / first)
    // 最初に戻る
    consthandleAllBack = (): void=> {
    if (currentPage === 1) {
    return
    }
    setCurrentPage(1)
    }
    // 1つ戻る
    consthandleBack = (): void=> {
    if (currentPage === 1) {
    return
    }
    setCurrentPage(currentPage – 1)
    }
    // 1つ進む
    consthandleForward = (): void=> {
    if (currentPage === totalPage) {
    return
    }
    setCurrentPage(currentPage + 1)
    }
    // 最後のページに進む
    consthandleAllForward = (): void=> {
    if (currentPage === totalPage) {
    return
    }
    setCurrentPage(totalPage)
    }
    // 番号クリック
    consthandleMove = (page: number): void=> {
    setCurrentPage(page)
    }
    // 範囲の指定
    letrangeStart: number = currentPage – 3
    if (rangeStart < 0) {
    rangeStart = 0
    }
    letrangeEnd: number = currentPage + 1
    if (rangeEnd > totalPage) {
    rangeEnd = totalPage
    }
    lettotalPageArray: number[] = Array.from(newArray(totalPage)).map(
    (_, i) => i++
    )
    totalPageArray = totalPageArray.filter((range) => {
    returnrangeStart <= range && range <= rangeEnd
    })
    // 省略された時に…で表示する
    constbeforeRange: boolean = rangeStart > 0
    constafterRange: boolean = rangeEnd + 1 < totalPage
    return (
    <>
    {totalPage > 1 && (
    <ulclassName={classNames(styles.pagination)}>
    <span
    className={classNames(
    `${styles.pageAllArrow}${styles.pageAllArrowPrev}`
    )}
    onClick={() =>handleAllBack()}
    ></span>
    <span
    className={classNames(
    `${styles.pageArrow}${styles.pageArrowPrev}`
    )}
    onClick={() =>handleBack()}
    ></span>
    {beforeRange ? <span>…</span> : null}
    {totalPageArray.map((page) => {
    page++
    returnpage === currentPage ? (
    <li
    key={page}
    className={classNames(
    `${styles.pageItem}${styles.pageItemActive}`
    )}
    >
    {page}
    </li>
    ) : (
    <li
    className={classNames(styles.pageItem)}
    key={page}
    onClick={() =>handleMove(page)}
    >
    {page}
    </li>
    )
    })}
    {afterRange ? <span>…</span> : null}
    <span
    className={classNames(
    `${styles.pageArrow}${styles.pageArrowNext}`
    )}
    onClick={() =>handleForward()}
    ></span>
    <span
    className={classNames(
    `${styles.pageAllArrow}${styles.pageAllArrowNext}`
    )}
    onClick={() =>handleAllForward()}
    ></span>
    </ul>
    )}
    </>
    )
    }
    export default Pagination