Day-14 Pagination vs Infinite scroll, State-Lifting

이영주·2022년 5월 26일
0
post-custom-banner

홈페이지에 페이지번호는 당연히 있어야 된다고 생각했는데.. 이제는 없어도 될 것 같다.. 영원히..
이해가 되는거 같으면서도 안되는 이 아이러니한 상황을 벗어나려면 역시 공부하는 수밖에ㅠ
홈페이지 만드는 모든 개발자들을 다시 한 번 존경합니당.. 이제 느리다고 뭐라하지 않을게요..

Infinite scroll

Infinite scroll이란 무한 스크롤이라고 하는데 페이지 하단에 도달했을 때 콘텐츠가 다른 페이지로 이동하지 않고 계속 로드되는 방식이다.

무한스크롤은 단일 페이지에서 끝없는 정보의 흐름을 보여주기 때문에 페이스북, 인스타그램 등에서 흔하게 볼 수 있다.
스크롤을 할 때마다 새로운 컨텐츠가 덧붙여져 흐름이 끊기지 않고 볼 수 있으며 모바일에서도 적합한 방식이다.

스크롤을 하면서 계속 새로운 글이 업데이트가 되는 것이 핵심이고 새로운 글이 없다면 이전스크롤만 나타나게 해야한다.


전체 댓글들을 보기 위해서는 이전댓글들+추가댓글들을 불러와야 하는데 배열로 구성된 댓글을 하나의 배열로 복사해오기 위해서는 스프레드 연산자(...)를 사용해야 한다! (얕은복사, 깊은복사 참고)

스프레드 연산자를 포함한 무한 스크롤을 코드로 작성해보면 위의 사진과 같다.

무한스클롤은 fetchMore 함수를 사용를 사용하는데 이전에 패치한거 말고 그 이후에 추가된거를 패치해주는 것을 말한다.

variables를 통해 다음페이지를 요청해 주어야하고 updateQuery를 통해 전체 댓글을 업데이트 한다.
variables의 페이지번호는 현재까지 요청한 페이지인 Math.ceil(data.fetchBoards.length / 10)에서 +1을 해줌으로써 다음페이지를 요청할 수 있다.
updateQuery에는 prev와 fetchMoreResult라는 2개의 변수를 받는데 prev는 기존 데이터를 말하고 fetchMoreResult는 추가로 받아올 데이터를 말한다.

여기에는 추가적인 댓글이 없을 때는 이전 댓글만 가져오도록 if문으로 먼저 가정해주는 것이 좋고
최종적으로 전체댓글들은 prev를 이용하여 이전댓글들을 불러오고 fetchMoreResult를 이용하여 추가댓글들을 불러온다.

Pagination

pagination이란 콘텐츠들을 여러 페이지로 나누는 방식이다.

일반적으로 정보를 전달하거나 연속적인 내용이 아닐 경우 많이 쓰이는 방식이다. 사용자가 특정한 콘텐츠를 찾고 있는 웹사이트에 유용하다.

pagination을 할 때는 페이지를 넘길 수 있는 페이지 숫자와 다음 페이지로 넘어갈 수 있는 버튼 등이 있어야 한다.

구현은

  • 페이지 숫자 만들기(span)
    (map을 이용하여 간단하게 코드를 작성 할 수 있다.)
  • 숫자에 onClick 기능 넣기
  • 숫자별로 id 넣어서 id에 맞는 페이지로 넘어가도록 event.target.id 지정
  • 목록을 불러오는 것이기 때문에 refetch 하기(playground 참고)
    (refetch할 때는 variables를 사용하지 않고 바로 page에 event.target.id 불러오기)

하지만 페이지 숫자를 일일히 작성할 수는 없으니 new Array로 빈 배열을 만들어 준 후 fill을 통해 값을 채워 index로 나열해줄 수 있고

이전 페이지와 다음 페이지로 이동하기 위해서는 기준페이지를 잡는 것이 중요하다!

map을 이용해서 한번에 10개씩은 나오게 설정을 해두었으니 그 중에 시작 지점인 1을 기준 페이지로 잡고 기준페이지 + 10을 통해 11, 21, 31 ... 페이지와 같이 다음페이지를 보여줄 수 있게 되며 기준페이지 - 10을 통해 이전페이지를 보여줄 수 있게 된다.

하지만 여기까지의 문제점은 페이지 목록이 없음에도 다음페이지가 빈 공간으로 계속 이어지거나 이전페이지가 1이하로는 -로 나오는 것이다.

이전페이지는 1페이지가 보이면 함수를 종료시키도록 if(startPage === 1) return을 적어 바로 해결할 수 있으나

다음페이지는 몇 가지 단계를 거쳐야한다.

  1. 마지막 페이지가 어딘지 계산하기
  2. 계산된 마지막 페이지가 스타트 페이지 + 10보다 클때만 다음페이지로 이동하도록 허락하기
  3. 마지막 페이지(10개 중)에서 내용이 없는 페이지는 화면에서 나오지 않도록 해주기

우선 결과는 아래 사진과 같다.

const lastPage = Math.ceil(전체갯수/10)

마지막 페이지는 전체갯수에서 10으로 나눈 후 나머지가 나오면 다음페이지가 필요하기 때문에 올림을 해주어 그 값이 전체 페이지가 나오도록 지정했다.

이후 마지막 페이지의 onClickNextPage를 눌렀을 때 startPage+10 <= lastPage를 통해 마지막 페이지가 스타트 페이지 + 10보다 클때만 다음페이지로 넘어갈 수 있도록 허용해 주었다.

마지막 단계로 내용이 없는 페이지는 화면에 나오지 않도록 해주기 위해 if문을 이용해 lastPage가 있으면 보여주고 없으면 빈 공간인 것을 구현하기 위해 return <span></span>을 사용했다.


State-Lifting

state를 사용할 때 형제 컴포넌트끼리 바뀌는 값을 같이 사용하고 싶은데 어떻게 해야할까?

형제 컴포넌트끼리는 props를 사용하여 주고 받지도 못하고 서로 줄 수 있는 방법이 없기 때문에 부모 컴포넌트에 state를 끌어올려 props를 받아 자식 컴포넌트가 동시에 state를 사용할 수 있게 하면 된다.

state-Lifting의 경우 Pagination에서도 사용할 수가 있어서 숙지하는 것이 좋다!
(아래 예시 사진 참고)

profile
= ["꼼꼼한", "프론트엔드 개발자"]
post-custom-banner

0개의 댓글