[Week2] Pagination - 2

tia·2022년 2월 20일
0

파이널프로젝트

목록 보기
8/9

🗂 Pagination

이전 포스팅에서는 Pagination 컴포넌트에 대한 설명을 했고,
이번 포스팅에서는 서버측 설정에 대해 설명한 후, createPagination.js에 대해 설명을 하고자 한다.

1. server 설정

우선 Helper 전체 목록을 불러오는 코드를 보면서 설명을 하겠다.

module.exports = {
  getFilteredList: async (req, res) => {
    
    // 설명 1
    const id = parseInt(req.params.id);
	
    // 설명 2
    let page = Math.abs(parseInt(req.query.page));
    let limit = Math.abs(parseInt(req.query.limit));

    // 설명 3
    page = !isNaN(page) ? page : 1;
    limit = !isNaN(limit) ? limit : 9;
	
    // 설명 4
    const skip = (page - 1) * limit;

    if (id === 0) {
      try {
        
        // 설명 5
        const allList = await helper.findAndCountAll({
          limit,
          offset: skip,
          where: {},
          attributes: { exclude: ['password', 'createdAt', 'updatedAt'] },
        });
        const { count, rows: list } = allList;
        
        // 설명 6
        const maxPage = Math.ceil(count / limit);
        res.send({ list, maxPage });
      } catch (e) {
        console.log(e);
      }
    } else {
      // 생략
      }
    }
  },
};

설명 1

클라이언트 측에서는 아래와 같은 주소로 서버에 정보를 요청한다.
http://localhost:3000/helperlist/category/0?page=1&limit=9
위의 주소에서 0인 부분이 바로 id에 할당될 값인데,
query string은 string으로 값이 전달되기 때문에, parseInt() 함수를 사용해서 정수로 바꾸어 주었다.


설명 2

pagelimitid와 마찬가지로, parseInt() 함수를 사용해서 정수로 일단 바꿔주었다.
그리고 pagelimit은 무조건 양수여야만 하므로, Math.abs() 함수를 사용해 무조건 양수가 나올 수 있도록 설정하였다.


설명 3
query string 값이 정수로 변환될 수 없을 경우를 생각하여,
pagelimit의 기본값을 각각 1와 9로 설정해주었다.


설명 4
skip이라는 변수에 무시할 게시물의 수를 담아준다.
만약, 2 페이지를 클릭하면, DB에서 처음 9개 게시물을 무시하고 10번째부터 9개의 게시물을 보여주게 된다.


설명 5
sequelize pagination 관련 문법이다.
limit에는 한번에 불러올 데이터의 갯수를 설정하고,
offset에는 건너뛸 데이터의 갯수를 설정하면 된다.


설명 6
총 페이지 갯수를 서버측에서 계산해서 클라이언트로 보내준다.
sequelize의 findAndCountAll() 문법을 사용해서 총 데이터 갯수를 불러와서
count 변수에 담아 준 후에, countlimit(한 번에 불러올 데이터 갯수)로 나누어 주면, 총 페이지 갯수를 구할 수 있다.
이렇게 구한 총 페이지 갯수를 maxPage 변수에 담아 클라이언트로 보내준다.

2. client 설정

2-1. 기본 정보 설정

이전 포스팅에서 언급했듯이, codesandbox에서 가져온 코드였기에
우리 프로젝트에 맞게끔 코드를 수정하면서 코드를 하나하나씩 뜯어봐야만 했다.

우선 Pagination 컴포넌트 코드를 보면 아래와 같은 코드가 있다.

const { pagination } = createPagination({
  numberOfPage: 5,
  currentPage,
  maxPage,
});

이 부분이 createPagination.js 파일로 보내는 정보들이 담겨 있는 부분이다.

  • numberOfPage: 한 번에 보여질 페이지 넘버의 갯수
  • currentPage: 내가 현재 위치해 있는 페이지 넘버
  • maxPage: 서버측에서 보낸 값을 그대로 전달

createPagination.js 파일에서는 아래와 같이 위의 정보들을 받아온다.

const createPagination = (info) => {
  const { numberOfPage, currentPage, maxPage } = info;
}

2-2. 예외 경우 설정

현재 위치해 있는 페이지 넘버가 maxPage보다 커지거나, 페이지 넘버가 1보다 작은 경우를 예외 경우 처리해주었다.

if (currentPage > maxPage || currentPage < 1) {
  return {
    pagination: [],
    currentPage,
  };
}

2-3. 필요한 변수 설정

  • pageNumList
const pageNumList = Array(maxPage)
  					.fill(1)
  					.map((x, idx) => x + idx);

만약 maxPage가 10 이라면,
pageNumList에는 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 배열이 담기게 된다.

  • sideBtn
  const sideBtn =
    numberOfPage % 2 === 0 ? numberOfPage / 2 : (numberOfPage - 1) / 2;

만약 numberOfPage가 5인 경우,
5 % 2는 0이 아니므로 콜론(:) 뒷부분이 실행되고, sideBtn에는 2가 할당된다.

즉, 5개의 페이지 넘버를 화면에 출력 할 경우,
가운데 페이지를 기준으로 양쪽에 몇개의 페이지 넘버를 출력할 것인지에 대한 정보를 담는 변수이다.

2-4. 왼쪽 화살표(이전 페이지) 설정

(bind() 메소드 공부한게 여기서 도움이 되는 구나 🙂🙃)

const calculLeft = (rest = 0) => {
  return {
    array: pageNumList
        .slice(0, currentPage - 1)
        .reverse()
        .slice(0, sideBtn + rest)
        .reverse(),
    rest: function () {
        return sideBtn - this.array.length;
    },
  };
};
  • array
    pageNumList는 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 이고, currentPage가 5 인 경우,
    출력되어야 하는 페이지 넘버들은 3 4 5 6 7 과 같다.
    currentPage를 기준으로 왼쪽에 위치한 3 4를 얻어내는 과정이다.

  • rest
    sideBtn은 위에서 계산한 결과 2가 할당되어 있고,
    this.array.length값은 현재 array에는 [3, 4]가 들어가 있기 때문에 2가 된다.
    그러므로 이 경우에서는 0이 return 된다.

2-5. 오른쪽 화살표(다음 페이지) 설정

const calculRight = (rest = 0) => {
  return {
    array: pageNumList.slice(currentPage).slice(0, sideBtn + rest),
    rest: function () {
      return sideBtn - this.array.length;
    },
  };
};

왼쪽 화살표(이전 페이지)와 비슷한 코드이므로 별도의 설명은 생략하겠다.

2-6. 화면에 출력되어야 하는 페이지 넘버 설정

const leftBtn = calculLeft(calculRight().rest()).array;
const rightBtn = calculRight(calculLeft().rest()).array;

CASE 1

pageNumList = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
currentPage = 1

leftBtn

  1. calculRight().rest() 실행
    • array에는 [2, 3] 배열이 할당됨
    • 최종적으로 0이 리턴됨
  2. calculLeft(0) 실행
    • 콘솔에 찍어보면 아래와 같은 결과가 출력됨
  3. calculLeft(calculRight().rest()).array = [ ]
  4. leftBtn = [ ]

rightBtn

  1. calculLeft().rest() 실행
    • array에는 [ ] 배열이 할당됨
    • 최종적으로 2가 리턴됨
  2. calculRight(2) 실행
    • 콘솔에 찍어보면 아래와 같은 결과가 출력됨
  3. calculRight(calculLeft().rest()).array = [2, 3, 4, 5]
  4. rightBtn = [2, 3, 4, 5]

CASE 2

pageNumList = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
currentPage = 6

leftBtn

  1. calculRight().rest() 실행
    • array에는 [7, 8] 배열이 할당됨
    • 최종적으로 0이 리턴됨
  2. calculLeft(0) 실행
    • array에는 [4, 5] 배열이 할당됨
  3. calculLeft(calculRight().rest()).array = [4, 5]
  4. leftBtn = [4, 5]

rightBtn

  1. calculLeft().rest() 실행
    • array에는 [4, 5]이 할당됨
    • 최종적으로 0이 리턴됨
  2. calculRight(0) 실행
    • array에는 [7, 8] 배열이 할당됨
  3. calculRight(calculLeft().rest()).array = [7, 8]
  4. rightBtn = [7, 8]

2-7. retun 해주어야지!

 return {
    pagination: [...leftBtn, currentPage, ...rightBtn],
    currentPage,
  };

2-6에서 얻은 변수들 값을 pagination에 담아서 리턴해주면,
페이지 넘버가 5개씩 일정하게 잘 출력된다.

3. 느낀점

비록 다른 누군가의 코드를 가져와서 우리 프로젝트에 적용했지만,
그만큼 코드에 대해 이해를 하고, 어떤 방식으로 동작이 되는 건지
내 나름대로 파악하려고 많은 노력을 했다.

클라이언트 코드는 좀 더 파악하기 쉽게 포스팅을 하면서 고쳐나갔지만,
createPagination.js 파일에 대한 코드도 좀 더 간단히 수정할 수 있으면 수정해 보고 싶다.

아직 구현해야할 기능들이 남아있기에, 이 부분은 추후 시간이 남을때 진행해 보도록 해야겠다.

0개의 댓글