[React--Monster예제 3] Limit과 offset을 활용해 pagination 구현하기

HUYKSKEE·2022년 8월 14일

그동안 해보고 싶었던 기능중 하나는 바로 pagination기능이다. 보통 구현을 하기전에 "어떻게"를 먼저 생각해보곤 하는데, 실제로 구현에 들어가기 전에 고민했던 시간이 비교적 많았다.

사고의 흐름 1

  1. fetch()로 데이터를 다 받아오고 useState에 저장.
  2. 1,2,3,...Next 버튼마다 onClick 이벤트를 이용한다.
  3. 이벤트가 일어날 대 실행되는 함수에는 각각의 데이터마다 부여된 id값을 이용해 조건문처리를 해준다.
  4. 참인 조건에 따라 데이터 list를 useState에 저장
    .
    .
    .
    이 방법은 버튼마다 조건이 달라야하고 그만큼 반복적인 코드가 많이 들어가기 때문에 아닌듯해서 포기.

포기 후

  1. 구글링을 해보니 페이지네이션 알고리즘을 이용한다는 걸 알게됨.
  2. offset과 limit값을 동적으로 사용해 map함수로 뿌려주는 방법이었다.

👆 실제 구현

  • 구현하려고 보니 예제코드에 어떻게 구현해야 되는지 설명한 주석이 있었다.
    백엔드에서 offset 과 limit 이라는 "키값"을 통해 데이터를 끊어서 보내줄 준비가 되어있습니다. 쿼리스트링을 사용해 mliit와, offset을 바꿔가며 요청을 보내보세요.
    오...이미 백엔드 쪽에서 준비가 되있을 줄은 생각도 못했다.

그렇다면 더욱 쉬워진 느낌이었다.

  • 받을때부터 limit과 offset을 활용해 끊어서 받아온다면, 직접 map함수를 꾸며야 할 일이 줄어든 셈이다.

구현 코드

export default function Users() {
  const [users, setUsers] = useState([]);
  const [offset, setOffset] = useState(0);

  // 데이터 로딩
  const LIMIT = 20;
  const nextOffset = LIMIT + offset;
  useEffect(() => {
    fetch(
      `http://localhost:8000/users?limit=${LIMIT}&offset=${nextOffset - 20}`
    )
      .then((res) => res.json())
      .then(setUsers);
  }, [nextOffset]);
  // useEffect에서 바뀌는 값은 nextOffset값이기에 의존성배열에 추가해준다~!

return (

<div className="photos">
  <h1>Mini Project - Pagination</h1>
  <Buttons offset={offset} setOffset={setOffset} />
  <CardList users={users} />
</div>

);
}

#### CardList 컴포넌트
```js
export default function CardList({ users }) {
  return (
    <div className="cardList">
      {users.map((user) => { 
    //이부분이 원래 users.slice(offset, offset + limit).map...이렇게 다 계산해줬어야함.
        return (
          <Card
            key={user.id}
            id={user.id}
            name={user.name}
            profileImage={user.profile_img}
            email={user.email}
            phoneNumber={user.phone_number}
          />
        );
      })}
    </div>
  );
}
  • 이미 받아올 때 부터 끊어서 받아오기 때문에 동적인 값들만 핸들링해주면 된다.

Button 컴포넌트

export default function Buttons({ offset, setOffset }) {
  return (
    <div className="pageBtn">
      <button
        className={offset === 0 ? "selected" : ""}
        onClick={() => {
          return setOffset(0);
        }}
      >
        1
      </button>
      <button
        className={offset === 20 ? "selected" : ""}
        onClick={() => {
          return setOffset(20);
        }}
      >
        2
      </button>
      <button
        className={offset === 40 ? "selected" : ""}
        onClick={() => {
          return setOffset(40);
        }}
      >
        3
      </button>
      <button
        className={offset === 60 ? "selected" : ""}
        onClick={() => {
          return setOffset(60);
        }}
      >
        4
      </button>
      <button
        className={offset === 80 ? "selected" : ""}
        onClick={() => {
          return setOffset(80);
        }}
      >
        5
      </button>
    </div>
  );
}
  • 삼항연산자를 이용해 offset값에 따라 className을 다르게 주었다.
  • 여기에서 동일한 코드의 중복이 굉장히 많이 들어가는게 좀 아쉽긴 하다.
profile
개가수(개발자 + 가수) 🙏개발자들의 공유 문화를 지향합니다.🤝

0개의 댓글