【React Native+Appwrite】获取数据时的分页机制

一、为什么要有分页

在实战开发中,如果需要做Feed流且上拉加载更多内容,说明后端肯定有很多的数据,那么向后端获取数据的时候,总不能一次性加载所有的数据吧,这样会导致加载速度变慢,且后端数据库的压力很大。

那么我们在获取数据的时候,可以分次获取,每次获取一定数量的数据,用户上拉的时候再拉取下一页,再发起一次请求,这就是分页机制

在Appwrite中常用的分页方式有两种:

  • 基于页码Offset分页
  • 基于游标Cursor分页

二、Offset分页(页码式分页)

Offset分页 是基于页码的,原理是记录当前的页码page,获取数据的时候从数据集中跳过前面的offset = (page - 1) * limit 条,获取limit条数据。

优点:

  • 逻辑直观好理解,实现简单
  • 适合数据量不大、不常变动的场景

缺点:

  • 数据频繁变动的时候(增加减少数据)可能会导致缺漏和重复,因为整体的数据会偏移
  • 数据量大的时候,需要跳过大量的数据,后端在处理的时候效率会降低

使用示例:

javascript 复制代码
import { Query } from "appwrite";
​
async function fetchPage_offset(page = 1, limit = 15) {
  const offset = (page - 1) * limit;
  const res = await databases.listDocuments(DB_ID, COLLECTION_ID, [
    Query.orderDesc("$createdAt"),  //排序
    Query.limit(limit),    //限制数据数量
    Query.offset(offset),  //偏移量
  ]);
  return res; // 返回来的数据在res.documents, 数量是res.total
}
​

使用场景: 小型数据集、开发期快速验证、或者你需要精准的"页码跳转到第x页"体验。

三、Cursor分页

Cursor分页 是基于游标的,原理是每次请求都按照某个顺序取一定数量的数据(一般是按照创建时间),取完以后拿出最后一条数据的ID 作为游标,下一次请求的时候从这个游标之后继续取,这样定位准确,不会缺漏记录。

相当于看书,往看到的地方插个书签,下次再读就不会找错了。

优点

  • 性能更高,数据库不需要跳过大量记录
  • 稳定性强,在数据被频繁插入和删除时更可靠,以游标为基础,不易缺漏和重复
  • 适合无限滚动的场景

缺点

  • 需要按稳定字段排序 (通常是创建时间$createdAt 或其它有索引的字段)
  • 实现时要处理排序方向(asc/desc)和 cursor 的关系
  • 无法直接跳转到某一页

使用示例

javascript 复制代码
import { Query } from "appwrite";
​
//第一次请求 
async function fetchFirstPage_cursor(limit = 15) {  
  const res = await databases.listDocuments(DB_ID, COLLECTION_ID, [
    Query.orderDesc("$createdAt"),  //排序
    Query.limit(limit),   //取limit条数据
  ]);
  return res; // 数据在res.documents, 数量是res.total
}
​
// 获取到数据后,保存最后一条数据的ID作为游标
// const lastDocId = res.documents[res.documents.length - 1].$id;
​
​
//下一页请求
async function fetchNextPage_cursor(lastDocId, limit = 15) {
  const res = await databases.listDocuments(DB_ID, COLLECTION_ID, [
    Query.orderDesc("$createdAt"),
    Query.cursorAfter(lastDocId),  //从游标处后面找起
    Query.limit(limit),
  ]);
  return res;
}
​

注意cursorAfter/cursorBefore 这两个方法是基于游标,不是基于时间戳。所以在使用的时候需要和排序结合使用,先排序后按游标查找,效果更稳定。

四、总结

  • 方法选择:

    • Offset分页:数据量小,需要直接跳转到第x页的场景,实现简单
    • Cursor分页:数据量大的大部分场景,例如Feed流、评论区、聊天记录或大型数据集,效果更好,但稍微复杂
  • 分页大小(limit):为了保证首屏加载的效率,量不需要太大,可以在8~20之间

  • 游标选择 :使用 Cursor 分页时,确保排序字段稳定且有索引(如 $id$createdAt,但Appwrite官方文档中使用的是id)。

  • 去重策略:不管使用什么方法分页,获取到新数据后,都要记得去重,以免出现重复的数据

  • 刷新(pull-to-refresh)策略:下拉刷新通常应该重新拉第一页,并替换列表数据而不是追加

相关推荐
冴羽2 小时前
这是一个很酷的金属球,点击它会产生涟漪……
前端·javascript·three.js
烛阴2 小时前
为什么 `Promise.then` 总比 `setTimeout(..., 0)` 快?微任务的秘密
前端·javascript·typescript
XiaoSong2 小时前
基于 React Native/Expo 项目的持续集成(CI)最佳实践配置指南
前端·react native·react.js
white-persist2 小时前
汇编代码详细解释:汇编语言如何转化为对应的C语言,怎么转化为对应的C代码?
java·c语言·前端·网络·汇编·安全·网络安全
张愚歌2 小时前
轻松打造个性化Leaflet地图标记
前端·javascript
华仔啊2 小时前
CSS实现高级流光按钮动画,这几行代码堪称神来之笔
前端·css
歪歪1002 小时前
详细介绍一下“集中同步+分布式入库”方案的具体实现步骤
开发语言·前端·分布式·后端·信息可视化
林太白2 小时前
rust17-部门管理模块
前端·后端·rust
_处女座程序员的日常2 小时前
如何预览常见格式word、excel、ppt、图片等格式的文档
前端·javascript·word·excel·开源软件