4번째, 프로젝트 리펙토링 : 3계층 나누기 - 03

이정기·2023년 2월 23일
0

TIL

목록 보기
49/71
post-thumbnail

프로젝트 때, 제대로 못만들어봤던 페이지네이션
주소창의 query , params 값을 어떻게 가져와서 처리하는지 정리


페이지네이션 백엔드

간단한 페이지네이션 형태로 구성

//reopsitory 데이터를 가져올 때,
  getUser = async page => {
    return await user.findAndCountAll({
      where: { userType: '0' },
      attributes: { exclude: ['password'] },
      offset: (page - 1) * 2,
      limit: 2,
    });
  };

인자의 page는 프론트에서 query 로 페이지 넘버를 넘기고, 그 페이지 넘버에 맞는 데이터 갯수를 보낼 생각이다.

sequelize 가 없을 땐, splice 를 사용해 새로운 객체를 복사해 자르고, 넘겨주는 번거로운 작업을 해야했는데, squelize 메서드를 이용하면 정말 간단하게 내가 원하는 갯수만큼 빼올 수 있었다.

시퀄라이즈 문법을 잘 정리해놓은 블로그

offset - 조회할 로우의 위치
limit - 조회할 로우의 갯수

페이지네이션을 구현하기 전 조건


이 것만 구현하는데 생각할 것들이 많았다.

  • 보이는 페이지 숫자는 1 - 5, 6 - 10 씩 5개
  • 게시글은 2개씩 보여질 예정
  • 첫 페이지에선 이전 버튼이 보이지 말아야한다.
  • 마지막 페이지에선 다음 버튼이 보이지 말아야 한다.

구해야할 것들

  1. 총 페이지 숫자 (totalPage)
  2. 보이는 페이지 기준 첫 번째 페이지 숫자 (firstPage) 1 - 5, 6 - 10 에서 1 과 6 부분
  3. 보이는 페이지 기준 마지막 페이지 숫자 (lastPage) 1 - 5, 6 - 10 에서 5 와 10 부분

모든 유저를 가져와 리스트에 보여줄 땐, findAll 메서드를 이용했지만, 총 페이지를 구하기 위해 불러온 데이터의 총 갯수를 알아야 했다. 다행이 편리하게도 시퀄라이즈에서 제공하는 findAndCountAll 메서드를 사용하면 자동으로 알려줬다.

1. 총 페이지 숫자 (totalPage)

findAndCountAll 딕셔너리 형태로 count 와 rows 를 자동으로 반환한다. 이 count 를 limit 값으로 나누면 총 페이지 숫자를 알 수 있었다.

let totalPage = Math.ceil(count / limit);

2. 첫 번째 페이지 숫자 (firstPage)

첫 번째 페이지는 마지막 페이지로 구하고, 공식이 있어 참고했다.

let firstPage = lastPage - 5 + 1 <= 0 ? 1 : lastPage - 5 + 1;

3. 마지막 페이지 숫자 (lastPage)

현재 보여지는 페이지 갯수를 그룹으로 묶고, 그 그룹의 마지막 페이지를 구하면 된다.

let pageGroup = Math.ceil(page / 5);
let lastPage = pageGroup * 5;

계산한 값들은 프론트에 보내 처리하면 끝.


페이지네이션 프론트 url query 가져오기

현재 페이지 값을 서버로 보내줘야 한다. 여기선 url에 query로 써서 정해진 코드로 가져왔다.

let query = window.location.search;
let param = new URLSearchParams(query);
let page = Number(param.get('page') || 1);

이 세개면 ?page=숫자 에서 숫자값을 가져오고, 숫자가 없다면 기본 1로 세팅해줬다.
우린 이 코드로 query를 가져오고 사용했다.

이전버튼과, 숫자, 다음버튼은 빈 배열을 선언 후, 분기문을 줘서 append 시켜주었다.


프론트 url prams 가져오기

유저를 상세조회 할 때, 유저의 id(primory key) 값을 url 안에 넣을 수 있는데 그걸 꺼내와 사용해야 했다.

const id = window.location.pathname.split('/')[2];
      getUserLists(id);

window.location.pathname 이 코드는 url 을 모두 string 형태로 가져와줬다. 이걸 필요한부분을 split 해주어 id 값을 가져올 수 있었다.

세션에 데이터 저장하고 사용해보기

쓸데없는 서버조회를 줄이기 위해 다음페이지에 같은 데이터를 쓴다면, 세션에 저장해 사용할 수 있었다. 진짜 편리한 기능!

sessionStorage.setItem('userDetails', JSON.stringify(row));

세션스토리지에 넣을 땐, 이름과 정보를 넣어주는데 정보는 JSON.stringify 메서드로 문자화를 시켜줘야 typeError 가 나지 않는다.

꺼낼때는 JSON.parse 로 다시 json 문법으로 만들어주면 데이터를 마치 서버에서 조회한것 같이 사용 할 수 있다.

const oneUser = JSON.parse(sessionStorage.getItem('userDetails'));

해당 페이지를 사용했다면, 스토리지를 비워줘야 하는데 지금은 세션스토리지에 하나만 저장하기 때문에 버튼을 눌렀을 때, 모든 세션스토리지를 비우는 코드를 작성했다.

sessionStorage.clear();

공식문서에선 세션스토리지는 브라우저탭에 종속되는 제약이 있어 잘 사용하진 않는다 한다.
그래서 로컬스토리지를 사용하는데 로컬스토리지의 특징은

localStorage의 주요 기능

오리진이 같은 경우 데이터는 모든 탭과 창에서 공유됩니다.
브라우저나 OS가 재시작하더라도 데이터가 파기되지 않습니다.
출처 - 모던 JavaScript

다음엔 로컬스토리지도 사용해봐야 겠다.

profile
Node.js 로 꿈을 꾸었다..

0개의 댓글