axios
로 db
데이터를 가져오는 함수를 만든다. 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버튼을 누를 때 그 페이지에 해당하는 데이터를 다시 요청하지 않아도 되는 부분이고, 단점이라면 불필요하게 다음 페이지 데이터를 불러온다는 것이다. 제일 단점은 내가 직접 만든 코드라서 쓸때없이 길고 이해가 안 갈수 있다. 이건 계속하면서 다듬어야할 부분이라고 생각한다..!