목표
- react-js-pagination 패키지를 사용해서 페이지네이션 컴포넌트 만들기
- 페이지네이션 기능 구현
결과 화면
1. react-js-pagination 패키지 설치하기
https://www.npmjs.com/package/react-js-pagination
react-js-pagination 패키지에 대한 자세한 설명은 npm 사이트를 참고한다.
타입스크립트로 설치된 리액트이기 때문에 타입스크립트 버전도 같이 설치한다.
yarn add react-js-pagination @types/react-js-pagination
또는
npm install react-js-pagination @types/react-js-pagination
2. Pagination 컴포넌트 css 또는 scss 작성하기
react-js-pagination 패키지의 경우, css가 없기 때문에 직접 css 또는 scss를 작성한다.
- src/assets/scss/components/pagination.scss
css/scss를 작성하고, 공통 css/scss에 import 하거나 페이지네이션을 사용한 페이지에 import 한다.
해당 scss는 예시일 뿐, 원하는 디자인으로 만든다.
.pagination {
display: flex;
justify-content: center;
align-items: center;
gap: 5px;
margin: 50px auto;
li {
width: 30px;
height: 30px;
border-radius: 50%;
background-color: $bg-light;
transition: all 0.3s;
&:hover,
&:active ,
&.active{
background-color: $bg-point;
color: $white;
}
&:nth-child(1),
&:nth-child(2),
&:nth-last-child(1),
&:nth-last-child(2) {
a {
align-items: baseline;
font-size: 20px;
}
}
a {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
font-size: 12px;
}
}
}
3. react-js-pagination 패키지의 Pagination 컴포넌트 사용하기
- src/pages/board/list/index.tsx
axios로 받은 전체 게시글 데이터를 slice() 해서 페이지네이션 별로 화면에 보여준다.
- Pagination 컴포넌트를 import 한다.
- [currentPost, setCurrentPost], [page, setPage] state 변수를 만든다.
- postPerPage, indexOfLastPost, indexOfFirstPost 변수를 만든다.
- handlePageChange() 클릭 이벤트를 만든다. 페이지네이션을 누를 때마다 몇 번째 페이지인지 알 수 있다.
- 최근 게시물부터 역순으로 출력하고 싶기 때문에 axios 데이터를 reverse() 한다.
- 전체 게시글 또는 페이지네이션이 바뀔 때마다 동작해야 하기 때문에 useEffect() 안에 [setCurrentPost] state 변수를 작성한다.
- axios 데이터를 첫 번째 게시글 인덱스 번호와 마지막 게시글 인덱스 번호로 slice() 해서 5개씩 노출시킨다.
import Pagination from 'react-js-pagination'
const BoardList = () => {
const [boardList, setBoardList] = useState<BoardType[]>([]) // axios에서 받아온 전체 게시글 데이터
const [currentPost, setCurrentPost] = useState<BoardType[]>(boardList) // 페이지네이션을 통해 보여줄 게시글
const [page, setPage] = useState<number>(1) // 현재 페이지 번호
const postPerPage: number = 5 // 페이지 당 게시글 개수
const indexOfLastPost: number = page * postPerPage
const indexOfFirstPost: number = indexOfLastPost - postPerPage
const handlePageChange = (page: number) => {
setPage(page)
}
useEffect(() => {
axios.get('http://localhost:3001/board')
.then((response) => {
setBoardList([...response.data].reverse())
})
.catch(function(error) {
console.log(error)
})
}, [])
useEffect(() => {
setCurrentPost(boardList.slice(indexOfFirstPost, indexOfLastPost))
}, [boardList, page])
return (
<div className="board-list">
<table>
...
</table>
<Pagination
activePage={page}
itemsCountPerPage={postPerPage}
totalItemsCount={boardList.length}
pageRangeDisplayed={5}
prevPageText={"‹"}
nextPageText={"›"}
onChange={handlePageChange}/>
</div>
)
}
export default BoardList
전체 코드
- src/pages/board/list/index.tsx
import { useState, useEffect } from 'react'
import { Link } from 'react-router-dom'
import axios from 'axios'
import dayjs from 'dayjs'
import Pagination from 'react-js-pagination'
import { BoardType } from '../../../interface/BoardType'
import Button from '../../../components/form/Button'
import Title from '../../../components/text/Title'
import './index.scss'
const BoardList = () => {
// state
const [boardList, setBoardList] = useState<BoardType[]>([]) // axios에서 받아온 게시글 데이터
const [currentPost, setCurrentPost] = useState<BoardType[]>(boardList) // 게시판 목록에 보여줄 게시글
const [page, setPage] = useState<number>(1) // 현재 페이지 번호
const postPerPage = 5 // 페이지 당 게시글 개수
const indexOfLastPost = page * postPerPage
const indexOfFirstPost = indexOfLastPost - postPerPage
const boardLength = boardList.length
const handlePageChange = (page: number) => {
setPage(page)
}
useEffect(() => {
axios.get('http://localhost:3001/board')
.then((response) => {
setBoardList([...response.data].reverse())
})
.catch(function(error) {
console.log(error)
})
}, [])
useEffect(() => {
setCurrentPost(boardList.slice(indexOfFirstPost, indexOfLastPost))
}, [boardList, page])
return (
<div className="board-list">
<Title children="Board list"/>
<h4>Total post : {boardLength}</h4>
<table>
<colgroup>
<col width="15%"/>
<col width="65%"/>
<col width="20%"/>
</colgroup>
<thead>
<tr>
<th>No</th>
<th>Title</th>
<th>Date</th>
</tr>
</thead>
<tbody>
{
currentPost.map((board, index) => {
return (
<tr key={index}>
<td>{index + 1}</td>
<td className="title"><Link to={`/board/${board.id}`}>{board.title}</Link></td>
<td>{dayjs(board.created_at).format('YYYY.MM.DD')}</td>
</tr>
)
})
}
</tbody>
</table>
<Pagination
activePage={page}
itemsCountPerPage={postPerPage}
totalItemsCount={boardList.length}
pageRangeDisplayed={5}
prevPageText={"‹"}
nextPageText={"›"}
onChange={handlePageChange}/>
<Link to="/board/create">
<Button children="Write" variant="primary"/>
</Link>
</div>
)
}
export default BoardList
#2.2
react-js-paginatnio 패키지를 설치하고,
scss를 작성해 디자인을 커스텀하고,
axios 데이터를 slice 해서
페이지네이션 기능이 동작하게 만들었다.
'React > 게시판 만들기(TS)' 카테고리의 다른 글
[리액트][타입스크립트] #5 게시판 만들기 - 수정, 삭제 페이지 (axios.patch, axios.delete) (0) | 2023.07.05 |
---|---|
[리액트][타입스크립트] #4 게시판 만들기 - 생성 페이지 (axios.post) (0) | 2023.07.05 |
[리액트][타입스크립트] #3 게시판 만들기 - 상세 페이지 (axios.get) (0) | 2023.07.05 |
[리액트][타입스크립트] #2.1 게시판 만들기 - 목록 페이지 (axios.get, dayjs) (0) | 2023.06.30 |
[리액트][타입스크립트] #1 게시판 만들기 - 페이지 세팅 및 라우터 연결하기 (0) | 2023.06.30 |