
使用React Query实现无限滚动
在这篇文章中,我将讨论React Query的Infinite Scroll功能,即无限滚动
介绍
只要你有用过社交媒体就会体验过无限滚动的功能, 像 X(我还是习惯叫 twitter ), Facebook, Linkedin, Instagram... 这些社交媒体都没有做分页的功能, 相反你只需一直向下滑动, 新的内容便可以不断的生成, 无限点击下一页的按钮.
但需要注意的是, 无限滚动其实也分页的一种实现方式, 只不过没有那么明显, 记住这点, 我们便可以继续往下看看无限滚动的代码实现 .
实践
我将使用我以前的项目来实现此功能, 所以我不会结束如何安装和配置 React Query . 如果你不熟悉, 网上有很多教程可以去看看.
到此我将假定你已经给你的项目配置好, 并且你已经熟悉基础的 React Query .
我会使用 Fake API, The JSON Placeholder 来提供一些模拟的 data.
详细数据你可以访问此处.
首先给组件 Todo 创建一个文件夹: src/Todo/index.tsx
通常情况下, 我会创建一个类型声明文件 types.ts
. 但是这个组件我只在这个文件中使用, 为了方便, 我就将类型声明一起写在index.tsx
中. 另外我也创建了一个名为 MAX_POST_PAGE
的常量.
Todo 仅使用数据中的 id 和 title , 并且每页数据数量限制为10.
之后就可以获取数据了:
注意, 上面代码中 pageParam 表示第几页, 我接收的为object对象, 需要解构后再使用.
目前为止, 我的 Todo 组件有这些内容:
现在就需要给 Todo 组件添加些内容.
创建一个 observer , 使用useRef
钩子将IntersectionObserver
类型作为泛型传递:
如果你不清楚这里的 observer
的作用, Observer
是一种设计模式, Wiki定义如下:
观察者模式是软件设计模式的一种. 在此种模式中,一个目标对象管理所有相依于它的观察者对象,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现. 此种模式通常被用在即时事件处理系统.
观察者模式, 就想它名字所说的, 它将观察对象的state, 如果对象的依赖发生跟新, oberserver
就会收到通知.
为什么要解释这些概念🤔, 因为我之后需要用 oberserver
来判断用户是否到达了页面底部, 如果到达后将触发 oberserver
开始传递获取下一页的数据🤯.
接下来使用 React Query 中的useInfiniteQuery
我们需要解构的内容: data, error message, fetchNextpage 这些 function, hasNextPage 属性, isFecthing 和 isLoading状态.
然后通过 queryKey
来传递 todos, 在 queryFn
上传递函数 fetchTodos,并在 getNextPageParam
上创建一个函数用来获取下一页,如果有数据,则递增并验证.
现在需要创建一个函数来观察用户是否达到页面底部.
如果你现在不理解这段代码, 别慌, 我下面会解释.
首先代码会观察 node (一些div
元素), 并验证状态是否为 Loading,如果是,不返回任何内容并退出该函数.
之后代码将验证我是否已经拥有 IntersectionObserver 的实例。 如果已经有,会断开连接,因为我不想创建观察者的多个实例.
如果代码验证没有 IntersectionObserver 的实例。 便会使用 new IntersectionObserver()
将 entries
作为箭头函数的参数传递. 现在代码将验证页面是否为同一页面、是否存在下一页并且未获取内容.
如果所有条件都验证通过,代码将调用 useInfiniteQuery
函数返回的 fetchNextPage()
.
之后代码将上面提到的 observer
传递给 node
恭喜你, 现在可以理解这些代码了.
之后使用 reduce 格式化数据, 方便使用:
接下来需要验证, 并返回可能的状态和值:
现在 Todo 组件中内容是这样:
在 main.tsx
中渲染 Todo 组件:
显示效果如下:
这效果不多谈, 希望你喜欢 React Query 这个工具.
感谢你看到这里!