#i realize that's weirdly phrased so eg:
1 messages · Page 1 of 1 (latest)
import React, { useState, useEffect } from 'react';
import { useRouter } from 'next/router';
import prisma from '../../lib/prisma';
const PAGE_LIMIT = 50; // Set a limit of 50 items per page
// Function to fetch data from the database
async function fetchData(query, page) {
const items = await prisma.items.findMany({
where: {
text: { contains: query }, // SQL: WHERE text LIKE '%<query>%'
},
skip: page * PAGE_LIMIT, // SQL: OFFSET <page * PAGE_LIMIT>
take: PAGE_LIMIT, // SQL: LIMIT <PAGE_LIMIT>
});
return items;
}
// Function to fetch the total count of items from the database
async function fetchTotalCount(query) {
const totalItems = await prisma.items.count({
where: {
text: { contains: query }, // SQL: WHERE text LIKE '%<query>%'
},
});
return totalItems; // SQL: SELECT COUNT(*) FROM items WHERE text LIKE '%<query>%'
}
export default function Page() {
const router = useRouter();
const { query, page: pageParam } = router.query;
const [searchPage, setSearchPage] = useState(pageParam ? parseInt(pageParam, 10) : 0);
const [items, setItems] = useState([]);
const [totalPages, setTotalPages] = useState(0);
// useEffect hook to fetch and set data whenever the searchPage or query changes
useEffect(() => {
const fetchAndSetData = async () => {
const fetchedItems = await fetchData(query, searchPage); // Fetch items for the current page
const totalCount = await fetchTotalCount(query); // Fetch the total count of items
setItems(fetchedItems); // Update the state with the fetched items
setTotalPages(Math.ceil(totalCount / PAGE_LIMIT)); // Calculate and set the total number of pages
};
fetchAndSetData(); // Execute the function to fetch and set data
}, [searchPage, query]);
// Function to handle page change
const handlePageChange = (newPage) => {
setSearchPage(newPage); // Update the searchPage state
router.push({
pathname: '/writings',
query: { query, page: newPage }, // Update the page query parameter in the URL
});
};
// Render the list of items and the pagination controls
return (
<div>
<ul>
{items.map((item, index) => (
<li key={index}>{item.text}</li>
))}
</ul>
<nav>
<button disabled={searchPage === 0} onClick={() => handlePageChange(searchPage - 1)}>
Previous
</button>
<span>Page {searchPage + 1} of {totalPages}</span>
<button disabled={searchPage + 1 === totalPages} onClick={() => handlePageChange(searchPage + 1)}>
Next
</button>
</nav>
</div>
);
}
So if a new record is added while navigating, just act like it always there from the backend's perspective right?
Realistically you probably wouldn't want to use a server action for this, it was just shorter for the example
I've seen a few calls with a pagination token, is that for nosql stuff?
because you could cache those queries with fetch so back/forth navigation stays fast
some databases cache pages on a single index for performance - or a pagination token
Probably used mostly with nosql
You can do it in sql, but it's not really necessary except maybe at extreme scale
Ah i see. I guess a pagination count for nosql would likely requite storing the counts separately and updating it on create delete operations 
ah, here we go - I haven't used mongo in a bit
https://engage.so/blog/a-deep-dive-into-offset-and-cursor-based-pagination-in-mongodb/
This article covers exploring cursor-based pagination in MongoDB and how to navigate the tricky parts.