오프셋 기반 페이지네이션과 커서 기반 페이지네이션은 데이터베이스에서 데이터를 페이지 단위로 가져오는 두 가지 일반적인 방법이다.
데이터를 가져올 때 오프셋(offset)과 리미트(limit)를 사용하여 명시된 개수의 항목을 건너뛰고 가져온다.
function App() {
const [users, setUsers] = useState([]);
const [page, setPage] = useState(1);
const limit = 20; // 한 페이지에 표시할 아이템 수
useEffect(() => {
const fetchUsers = async () => {
try {
// 페이지 번호와 limit을 곱하여 offset 값을 계산합니다.
const offset = (page - 1) * limit;
// 데이터베이스에서 offset부터 limit까지의 아이템을 가져옵니다.
const response = await axios.get(`/users?offset=${offset}&limit=${limit}`);
setUsers(response.data);
} catch (error) {
console.error('Error fetching users:', error);
}
};
fetchUsers();
}, [page]);
return (
<div>
<h1>Users</h1>
<ul>
{users.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
<button onClick={() => setPage(page => page + 1)}>Next Page</button>
</div>
);
}
offset: 지금까지 받아온 데이터 개수
limit: 한 페이지에 표시할 아이템 수
전체 데이터가 20개이고 페이지당 표시할 항목의 수가 10개인 경우)
// 첫 번째 페이지의 데이터를 가져올 때
const offsetFirstPage = 0;
const limit = 10;
// 데이터베이스에서 0부터 limit(10)까지의 아이템을 가져온다.
// 따라서 첫 번째 페이지에는 첫 10개의 항목이 표시된다.
// 두 번째 페이지의 데이터를 가져올 때
const offsetSecondPage = 10;
// 데이터베이스에서 10부터 limit(10)까지의 아이템을 가져온다.
// 따라서 두 번째 페이지에는 11번째부터 20번째까지의 항목이 표시된다.
첫번째 페이지에서는 offset이 0이므로 데이터베이스에서 0부터 limit만큼의 아이템을 가져온다.
두 번째 페이지에서는 offset이 limit의 배수가 되므로 다음 limit만큼의 아이템을 가져온다.
페이지를 변경할 때마다 이전 페이지의 아이템을 건너뛰고 새로운 페이지의 아이템을 가져오는 원리다.
데이터베이스의 크기와 사용 사례에 따라 오프셋 기반 페이지네이션과 커서 기반 페이지네이션 중에서 선택할 수 있다.
데이터베이스가 작고 변경이 자주 일어나지 않는 경우에는 오프셋 기반 페이지네이션을 사용할 수 있지만,
대용량의 데이터나 변경이 빈번한 경우에는 커서 기반 페이지네이션을 사용하는 것이 좋다.
function App() {
const [users, setUsers] = useState([]);
const [cursor, setCursor] = useState(null); // 초기 커서는 null로 설정
const perPage = 10; // 페이지당 보여질 개수
useEffect(() => {
const fetchUsers = async () => {
try {
const response = await axios.get(`/users?cursor=${cursor}&limit=${perPage}`);
setUsers(response.data.users);
setCursor(response.data.next_cursor); // 다음 페이지의 커서를 설정
} catch (error) {
console.error('Error fetching users:', error);
}
};
fetchUsers();
}, [cursor, perPage]);
return (
<div>
<h1>Users</h1>
<ul>
{users.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
{cursor && <button onClick={() => setCursor(cursor)}>Next Page</button>}
</div>
);
}
초기 커서를 null로 설정하고, 페이지를 로드할 때마다 해당 페이지의 커서를 사용하여 다음 페이지의 데이터를 가져오도록 한다.
페이지당 보여질 개수를 perPage 상수로 설정하고, 커서 기반 페이지네이션을 구현할 때 각 페이지마다 이 값을 사용하여 쿼리를 수행한다.