TIL-React Pagination

배상건·2022년 4월 13일
3

TIL

목록 보기
9/15

학습하기 전 : Pagination은 프론트앤드에서만 구현하면 될 것이다!

학습 후 : Pagination은 프론트엔드, 백엔드 양쪽에서 모두 구현해야한다.

프론트엔드에서 현재 위치(Offset)과 추가로 보여줄 컨텐츠의 수(Limit)를
백엔드에 전달해야하기 때문이다.

여기서 잠깐!

Limit와 Offset은 어떤 개념일까?

  • Limit(= page size) : 한 페이지에 보여줄 데이터의 수
    page number : 1
  • Offset : 데이터가 시작하는 위치(index)
    <내가 착각한 포인트!> 데이터는 배열로 구성되어 있기 때문에, 항상 0에서 출발한다는 것을 잊지 말자!

Offset === index

1. 페이지네이션(Pagination)이란?

인터넷 뉴스 사이트에는 지금까지 축적된 수많은 기사들이 있을 것이다.
그런데, (1) 뉴스 페이지에 접속할 때마다, (2) 지금까지 축적된 모든 기사들을 한번에 다운 받는다면 어떻게 될까?

아마, 매번 접속 할 때마다 몇 시간을 대기하거나, 접속이 안될 때가 많을 것이다.

그래서 뉴스 사이트에서는 이러한 불편함을 덜기 위해, 기사들을 조금씩 받아서 사용자에게 보여준다.

즉, 페이지네이션이란,

렌더링에 필요한 데이터만 받아오는 것이다.

이때, 더 많은 자료를 확인하고 싶다면, <더보기 버튼>이나 스크롤을 내려 데이터를 추가로 받아오게 된다.

이렇게 데이터를 조금씩 나눠서 가져오는 것을 페이지네이션이라고 한다.

2. 페이지네이션의 종류

1) 오프셋 기반 페이지네이션

오프셋(Offset)
= 상쇄하다.
쉽게 말해, 지금까지 받아온 데이터의 개수라고 생각하면 된다.

예를 들어서
지금 까지 받아온 글가 20개(Offset)라면, 서버에게 다음 데이터를 10개만 더 보내달라고 요청하는 것이 오프셋 기반 페이지네이션이다.

위 그림의 쿼리를 보면,

offset=20 이 지금까지  받아온 데이터 개수이고,
limit=10 서버로부터 요청한 더 받아올 데이터의 개수이다.

클라이언트에서 offset=20&limit=10 을 요청(Request)하게 되면,
서버는 Respone로 데이터를 보내주게 된다.

<잠깐!!> 지금은 클라이언트에서의 요청 작업만 공부했기 때문에, 아래 그림과 같이 Respone가 구성되어 있다는 정도만 파악했다.

1_1) 오프셋 기반 페이지네이션의 문제점 : 중복 수령

오프셋 기반에서는 갯수를 기준으로 데이터를 나눈다.

예를 들어서,
전체 데이터 : 데이터가 1번부터 30번까지 있을 때
받아온 데이터 : 받아온 데이터는 1번부터 20번까지 받아왔고,
받아올 데이터 : 받아올 데이터는 21번부터 30번까지다.

그런데, 데이터가 새로 추가된다면??

뉴스 기사를 열람하는 도중에 새로운 기사가 추가된다고 했을 때,
Requset( offset=20 & limit=10 )를 보내면 어떻게 될까?
서버로부터 offset = 20 & limit = 10 으로 데이터를 받으면,
21번부터 30번까지 데이터를 받아와야지, 원래 의도대로 뉴스 기사를 열람할 수 있을 것이다.

그러나, 오프셋 기반 페이지네이션은 데이터의 갯수를 기준으로 데이터를 받아오기 때문에,
새로 추가된 데이트로 인해, 20번부터 29번까지 데이터를 받아오게 된다.

즉, 20번 데이터를 중복으로 받아오는 문제가 생긴다.

기존 데이터가 삭제되어도 동일한 문제를 갖는다.

원래 의도는 21번부터 30번까지 데이터를 추가로 받아와야 하는데,
기존 데이터가 삭제되면서, 22번부터 20번까지 데이터를 받아오게 된다.
이로인해, 21번 데이터를 받아오지 못하는 문제가 발생된다.

오프셋 기반 페이지네이션의 문제점(데이터 중복 및 누락)을 보완하기 위해 등장한 기술이 커서 기반 페이지네이션이다.

2) 커서 기반 페이지네이션

커서(Cursor)
= 데이터를 가리키는 값
쉽게 말해, 지금까지 받은 데이터를 표시하는 책갈피라고 생각하면 된다,

예를 들어, 클라이언트가 서버로 데이터를 10개만 보내달라는 요청(Requset)을 보내면,

서버는 응답(Response)으로 데이터와 페이지네이션 정보를 보내주게 되며,
페이지네이션 정보에는 다음 커서 값도 포함되어 넘겨지게 된다.

Response
{
	"paging":{
    	"count": 30,
        "nextCursor": "WerZxc" // 다음 커서 값!!!
    },
    "posts": [...]
}

서버로부터 페이지네이션 정보가 전달(Response)된 뒤, 다음 페이지를 불러 올 때부터,함께 받아온 커서 값으로 요청(Requset)을 보내게 된다.
즉, 전달 받은 커서(nextCursor)를 기준으로 서버에 데이터를 요청하게 된다.

2_1) 커서(nextCursor) : 오프셋 기반 문제 해결

따라서, 커서를 사용하면,
만약, 뉴스 기사를 열람하는 도중에 새로운 기사가 추가되더라도, 커서가 가리키는 값은 변하지 않게 된다.

(왜? Response 객체로 전달받은 페이지네이션 정보에 nextCursor가 존재하기 때문이다.)

이러한 이유로, 오프셋 기반과 달리
데이터의 중복이나 누락 없이 가져올 수 있게 된다.

2_2) 커서 기반 페이지네이션의 단점

커서 기반이 오프셋 기반의 문제점을 보완했는 것은 큰 장점이면서도, 큰 단점이기도 하다.
이는 서버 입장에서 커서 기반이 오프셋 기반보다 구현하기가 까다롭고,
데이터가 자주 수정되는 것이 아니라면, 오프셋 기반으로도 충분하기 때문이다.

3. 정리

페이지네이션(Pagination)

오프셋 기반 = 받아온 개수 기준
커서 기반 = 데이터를 가리키는 커서 기준

포스트를 마치며...

오늘은 페이지네이션에 대한 개념 정리로 만족하고,
주말 동안, 오프셋 기반과 커서 기반으로 데이터를 추가로 받아오는 연습을 수행하겠다.

참고 : 코드잇 React로 데이터 다루기-2 데이터 가져오기-09.페이지네이션이란?

profile
목표 지향을 위해 협업하는 개발자

1개의 댓글

comment-user-thumbnail
2022년 4월 17일

아주 정리를 깔끔하게 해주셔서 이해가 쏙쏙됩니다~
특히 오프셋기반의 단점과 커서기반 페이지네이션을 알게 되어 좋았습니다. 정말 잘봤어요~!
다만 들어주신 예시는 전통적인 페이지네이션보다는 더보기 페이지네이션의 예시라 할 수 있어요! 그래서 더보기 페이지네이션의 특성상, 현재 위치를 유지하기 위해 항상 offset값을 보존하고 있어야 하는거죠.

오프셋기반 페이지네이션으로 전통적인 페이지네이션도 구현 가능합니다. 전통적인 방식에서는 갑자기 1페이지에서 10페이지를 클릭하게 될 수도 있잖아요? 현재까지 받은 데이터가 10이든 20이든 간에, 그냥 10페이지에 해당하는 offset값을 보내면 됩니다. skip값이라고 보셔도 무방합니다. 전체 데이터가 총 몇페이지까지 존재하는지 totalCount 값을 항상 받아 계산하여 나타내게 되구요.

즉, 전통적인 페이지네이션에선 현재 offset값을 기억할 필요없이, 항상 새롭게 원하는 page(혹은 offset), limit을 request로 보내면, 해당하는 데이터와 totalCount값이 새롭게 갱신되어 response된다고 할 수 있습니다. 항상 새롭게 갱신해서 받아오기 때문에 중간에 데이터가 추가되거나 삭제되어도 큰 문제가 없을 수 있습니다!

추가로 블로깅하신 부분에서 궁금해하셨던 Respone에 전달되는 내용이 무엇인지 해석해드리자면,

  • count는 새로운 offset값이라고 보면 됩니다. offset=20, limit=10으로 request를 보내셨기 때문에 20 + 10 => 즉, 현재까지 총 30개의 데이터를 받은 상태임을 나타내는거지요.
  • hasnext는 다음 데이터가 있는가에 대한 부분인데, false이므로 30개가 전체 데이터 개수이고 이제 더 불러올 데이터는 없다고 해석할 수 있을 것 같습니다.
  • 마지막으로 post는 limit을 10으로 설정하신만큼 10개의 게시글의 메타데이터가 담겨있다라고 할 수 있습니다. 다만 당장 페이지네이션을 설명하는데 있어선 딱히 필요없는 정보이므로 [...] 표현하여 그냥 생략한 것이라고 보면 됩니다!
답글 달기