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

HUYKSKEE·2022년 8월 14일
1

그동안 해보고 싶었던 기능중 하나는 바로 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개의 댓글