📖 14일차 회고록
지금까지 배운 것중에 가장 힘들었다.....😭
뭔가 이해하기보다 따라가기 급급했던 페이지네이션과 state 끌어올리기
내용이 많으니까 나눠서 써야겠다
복습은 무조건 2번 , 3번 필수!
💡페이지 번호를 클릭해서 이동하는 방식의 페이지 처리방법 (게시판 형태에서 가장 많이 쓰임)
📌페이지네이션 구성단계
- fetchBoardsAPI 활용하여 게시글 목록 불러오기
//fetch query에
const FETCH_BOARDS = gql`
query fetchBoards($page: Int) {
fetchBoards(page: $ page) {
_id
writter
title
}
}
`
//fetchBoards
const {data} = useQuery(FETCH_BOARDS, {variables: { page: 1 } } ) ;
return(
<div>
{data?fetchBoards?.map((el) => (
<div key={el.id}>
{el.title} {el.writer}
</div>
</div> //map함수를 통해 fetchBoards id, title, writer값 받기
)
- 페이지 클릭시 게시글 목록 데이터 다시 불러오기(refetch)
graphQL의 useQuery에서 제공하는 refetch함수 활용하면
페이지 클릭 시 해당 페이지에 해당하는 데이터를 다시(re) 불러올(fetch)할 수 있음
사용하려면 useQuery에서 data와 refetch 함수를 가져와야함
//fetchBoards, data와 refetch 가져오기
const {data, refetch } = useQuery(FETCH_BOARDS, {variables: { page: 1 } } ) ;
const onClickPage = (event) => {
//위에서 가져온 refetch 사용하기
refetch({ page: Number(event.target.id }) ;
}
return(
<div>
{data?fetchBoards?.map((el) => (
<div key={el.id}>
{el.title} {el.writer}
</div>))}
<span onClick = {onClickPage} id="1">1</span>
<span onClick = {onClickPage} id="1">2</span>
<span onClick = {onClickPage} id="1">3</span>
</div>
)
- map을 이용해 페이지네이션 뿌리기 (1~10page)
{[1,2,3,4,5,6,7,8,9,10].map(el) => (
<span onClick = {onClickPage} id={String(el)} key={el}>
{` ${el} `}
❗만약 10페이지 이상이라면 어떻게?❗
- 페이지네이션 next / prev 구현
{new Array(10).fill(1).map((_, index) => ( // 길이 10의 새로운 배열을 만들어 1로 채움
<span
onClick={onClickPage}
id={String(index + startPage)} //id는 시작페이지 + index값
key={index + startPage}
>
{` ${index + startPage} `}
</span>
))}
이제 startPage의 state값을 변경하면 startPage에 따라 앞뒤로 10페이지 불러오기 가능
export default function PaginationNextPage() {
// 시작 페이지 state값 주기
const [startPage, setStartPage] = useState(1);
// 이전 페이지 클릭 시 실행할 함수 추가
const onClickPrevPage = () => {
setStartPage((prev) => prev - 10); // 이전페이지 클릭하면 현재보다 -10
};
// 다음 페이지 클릭 시 실행할 함수 추가
const onClickNextPage = () => {
setStartPage((prev) => prev + 10); // 다음페이지 클릭하면 현재보다 + 10
};
))}
return(
<div> //prev, next 페이지 버튼(span) 추가하기
<span onClick={onClickPrevPage}>이전페이지 |</span>
<span onClick={onClickNextPage}> 다음페이지</span>
</div>
)
❗여기까지 설정해주면 작동은 되지만 마지막페이지를 넘어서도 계속 작동함
- lastPage 설정
const FETCH_BOARDS_COUNT = gql`
query fetchBoardsCount {
fetchBoardsCount
}
` // 먼저 DB에 등록된 게시글의 총 개수를 불러와서 마지막 페이지 값을 구함(fetchBoardsCount)
const lastPage = Math.ceil(dataBoardsCount?.fetchBoardsCount / 10) ;
// 10페이지씩 보여주기 때문에 만약 게시글수가 151개라면 16페이지가 있어야함.
// 10으로 나누고 올림을하면 된다.
❗이제 1페이지 미만, lastPage 이후로는 버튼이 동작되지 않도록 해야함
const onClickPrevPage = () => {
//startPage가 1이면 종료
if(startPage === 1 ) return;
}
const onClickNextPage = () => {
// startPage + 10이 lastPage보다 크면 종료
if(startPage + 10 > lastPage) return; }
❗map에 조건부 렌더링을 걸어서 lastPage보다 큰 숫자는 출력되지 않도록 함
{new Array(10).fill(1).map((_, index) =>
index + startPage <= lastPage && ( //index+ startPage <= lastPage면 실행 아니면 x)
<span
onClick={onClickPage}
id={String(index + startPage)}
key={index + startPage}
>
{` ${index + startPage} `}
</span>
))}
❗이전페이지, 다음페이로 이동할때도 게시글 목록이 함께 이동해야함 -> refetch
const onClickPrevPage = () => {
refetch({ page: startPage - 10 });
};
const onClickNextPage = () => {
refetch({ page: startPage + 10 });
};
// 클릭버튼에 리패치 추가하기.
☑️ 결과