【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)策略:下拉刷新通常应该重新拉第一页,并替换列表数据而不是追加

相关推荐
fanruitian4 小时前
uniapp android开发 测试板本与发行版本
前端·javascript·uni-app
rayufo4 小时前
【工具】列出指定文件夹下所有的目录和文件
开发语言·前端·python
RANCE_atttackkk4 小时前
[Java]实现使用邮箱找回密码的功能
java·开发语言·前端·spring boot·intellij-idea·idea
摘星编程5 小时前
React Native + OpenHarmony:Timeline垂直时间轴
javascript·react native·react.js
2501_944525545 小时前
Flutter for OpenHarmony 个人理财管理App实战 - 支出分析页面
android·开发语言·前端·javascript·flutter
jin1233226 小时前
React Native鸿蒙跨平台完成剧本杀组队详情页面,可以复用桌游、团建、赛事等各类组队详情页开发
javascript·react native·react.js·ecmascript·harmonyos
李白你好6 小时前
Burp Suite插件用于自动检测Web应用程序中的未授权访问漏洞
前端
刘一说7 小时前
Vue 组件不必要的重新渲染问题解析:为什么子组件总在“无故”刷新?
前端·javascript·vue.js
jin1233227 小时前
基于React Native鸿蒙跨平台移动端表单类 CRUD 应用,涵盖地址列表展示、新增/编辑/删除/设为默认等核心操作
react native·react.js·ecmascript·harmonyos
徐同保8 小时前
React useRef 完全指南:在异步回调中访问最新的 props/state引言
前端·javascript·react.js