del*_*esb 1 javascript reactjs next.js prisma swr
我正在尝试使用 Nextjs、Prisma 和 SWR 创建一个分页表。该表将显示按 ID 排序的发票列表。这是它的外观示例:
我使用Prisma将所有数据获取到 api 路由,并使用 SWR在 UI 上显示数据并重新验证。这是迄今为止的 UI 代码:
{InvoiceData.map((invoice, key) => {
return (
<tr key={key}>
<td className="font-medium">
#
{invoice.nro_factura &&
Number(invoice.nro_factura).toString()}
</td>
<td className="whitespace-pre-wrap">
{invoice.fecha_emision &&
moment(invoice.fecha_emision).format("MMM DD, YYYY")}
</td>
<td className="font-medium">
${invoice.total && Number(invoice.total).toLocaleString()}
</td>
<td>
<Badge
status={
invoice.total === invoice.pagos
? 0
: invoice.anulada
? 2
: 1
}
title={
invoice.total === invoice.pagos
? "Pagado"
: invoice.anulada
? "Borrada"
: "Pendiente"
}
/>
</td>
<td className="customer-column">
{CustomersData.map((customer) => {
if (customer.cliente_id === invoice.cliente_id) {
return customer.nombre_clte;
}
return null;
})}
</td>
</tr>
);
})}
Run Code Online (Sandbox Code Playgroud)
这是 api 路由内的代码:
import { prisma } from "../../../prisma/index.ts";
export default async function getInvoicesData(req, res) {
let InvoiceData = await prisma.factura.findMany({
orderBy: {
nro_factura: "desc",
},
});
return res.status(200).json(InvoiceData);
}
Run Code Online (Sandbox Code Playgroud)
NG2*_*235 14
分页有两种类型:偏移分页和光标分页。偏移分页的工作原理是跳过一定数量后获取行。游标分页的工作原理是对行进行排序,然后获取游标属性(即 ID)大于传递的游标值(即前端最后一行的 ID)的行。
抵消
需要将查询参数发送到 API 路由,例如page。该参数可以代表表格底部的页码。将该负 1 ( page - 1) 乘以每页的结果数 ( (page - 1) * size)。通过 Prisma 将其作为 发送到数据库skip。这将跳过表的前 X 行。您还必须包含该take参数,否则您将提取表的所有结果,不包括 之前的行skip。
一个例子:
const results = await prisma.post.findMany({
skip: 10, // How many rows to skip
take: 10, // Page size
})
Run Code Online (Sandbox Code Playgroud)
然后,您的 API 查询可能如下所示:https://example.com/api/invoices?page=2。如果页面大小为10,则页面2将包含“number”行11-20(跳过(2 - 1) * 10 = 10( (page - 1) * size))。
然而,当行数很多时,他的速度可能会变慢。另一种方法是光标分页(见下文)
光标
这将需要按 ID 排序的查询。您仍然需要获取一定数量的行(即 10 行),并将最后一项的 ID 作为游标传递(对于第 2 页及以上页面):
const firstQueryResults = await prisma.post.findMany({
take: 10, // Page size
skip: 1, // Skip the cursor row
cursor: {
id: myCursor, // The cursor - only on pages 2 and above
},
orderBy: {
id: 'asc', // Ordering results
},
})
Run Code Online (Sandbox Code Playgroud)
这将获取 ID 大于光标的所有行(即myCursor)
使用 API 请求中的查询参数cursor来设置光标。
光标分页速度要快得多,但是需要排序。也可以按时间戳排序。然后,您只需要按查询中的时间戳进行排序。
前端
然后,您可以在前端使用 API 响应中的数据更新存储结果的变量。我建议您在 API 响应中包含一个包含行数的属性(count来自 Prisma),以便您可以除以页码并在表格底部显示正确的按钮数量。
对于偏移分页,单击按钮时,将页码作为查询参数发送到 API。
对于光标分页,简单地使用下一个和后退按钮会更容易。对于下一个按钮,通过发送光标来分页。对于返回,取负数行(即-10) - 这可以通过设置另一个查询参数来完成,例如direction(您将需要实现此逻辑)。可以有页码;您需要做的就是使用页面之间的行数差异cursor。skip(例如,从第2页转到第5页会跳过第3页。因此,您需要使用第2页上最后一项的光标,并跳过第3页和第4页的结果数(即20))
根据 SWR 文档,您可以创建一个传递给页面的 API 查询的变量。可以将其修改为光标和方向。
function App () {
const [pageIndex, setPageIndex] = useState(0);
// The API URL includes the page index, which is a React state.
const { data } = useSWR(`/api/data?page=${pageIndex}`, fetcher);
// ... handle loading and error states
return <div>
{data.map(item => <div key={item.id}>{item.name}</div>)}
<button onClick={() => setPageIndex(pageIndex - 1)}>Previous</button>
<button onClick={() => setPageIndex(pageIndex + 1)}>Next</button>
</div>
}
Run Code Online (Sandbox Code Playgroud)
额外的改进
您可以通过将其作为查询参数发送来动态设置限制或页面大小
| 归档时间: |
|
| 查看次数: |
5706 次 |
| 最近记录: |