[React] Pagination (json-server, axios)

Hwanhoon KIM·2023년 8월 1일
0

axiosdb데이터를 가져오는 함수를 만든다. json-server를 사용하므로 다음과 같이 url을 작성할 수 있다.

/database?_limit=5&_page=${pageNumber}
_limit=5: 5개씩 데이터를 제한한다.
_page=1: 페이지를 1로 지정한다.
즉, /database에 데이터가 10개 있으면, 처음 5개는 /database?_limit=5&_page=1에서 확인할 수 있으며, 다음 5개 데이터는 /database?_limit=5&_page=2에서 확인할 수 있겠다.

export const getTodoDB = async (pageNumber: number): Promise<any> => {
  return await requestDB(`/database?_limit=5&_page=${pageNumber}`);
};

컴포넌트에서 pageNumber 상태를 생성한다.

const [pageNumber, setPageNumber] = useState<number>(1);

useQuery를 통해 데이터를 받아온다. 여기서 주목할 점은 keepPreviousData: true로 설정해놓는것이다. 그러면 매번 페이지가 바뀔 때 마다 기존에 한 번 로드되었던 페이지는 새로 서버에 요청을 보내지 않고 캐시에서 받아서 바로 보여준다.

const { data } = useQuery({
    queryKey: ['todoList', pageNumber],
    queryFn: () => getTodoDB(pageNumber),
    keepPreviousData: true,
  });

그리고 return에서 이전페이지, 다음페이지 버튼을 만든다.

거기에 setPageNumber함수를 넣는다.

<button
  onClick={() => setPageNumber(pageNumber - 1)}
  disabled={pageNumber === 1}
>
  Previous page
</button>

<button
  onClick={() => setPageNumber(pageNumber + 1)}
  disabled={!nextPageData?.length}
>
Next page
</button>

위 코드에서 Previous page 버튼은 현재 페이지가 1일때 비활성화되며, next page 버튼은 nextPageData가 존재하지 않을 때 비활성화 된다.

nextPageData를 받는 로직은 다음과 같다.

const testData = useQuery({
  queryKey: ['todoList', pageNumber + 1],
  queryFn: () => getTodoDB(pageNumber + 1),
  keepPreviousData: true,
});
const nextPageData: Array<T_todoList> = testData?.data?.data;

단순히 pageNumber + 1한 값을 쿼리로 미리 불러와서 데이터가 있는지 없는지 확인할 뿐이다. 여기에서 장점은 다음 페이지를 미리 로드해서 next버튼을 누를 때 그 페이지에 해당하는 데이터를 다시 요청하지 않아도 되는 부분이고, 단점이라면 불필요하게 다음 페이지 데이터를 불러온다는 것이다. 제일 단점은 내가 직접 만든 코드라서 쓸때없이 길고 이해가 안 갈수 있다. 이건 계속하면서 다듬어야할 부분이라고 생각한다..!

profile
Fullstack Developer, I post about HTML, CSS(SASS, LESS), JavaScript, React, Next, TypeScript.

0개의 댓글