当前位置:首页 > 科技  > 软件

如何使用 React Query 做下拉数据自动刷新?

来源: 责编: 时间:2024-07-02 17:37:24 75观看
导读useInfiniteQuery() API看名字就能猜出来,useInfiniteQuery() 是专门用来应付无限查询场景的。不仅如此,useInfiniteQuery() API 能力也是基于 useQuery() 的。之前的文章中我们介绍了 useQuery() 的核心 API,为了找回印

useInfiniteQuery() API

看名字就能猜出来,useInfiniteQuery() 是专门用来应付无限查询场景的。不仅如此,useInfiniteQuery() API 能力也是基于 useQuery() 的。0jX28资讯网——每日最新资讯28at.com

之前的文章中我们介绍了 useQuery() 的核心 API,为了找回印象,我们在此贴出来:0jX28资讯网——每日最新资讯28at.com

import { useQuery } from 'react-query'const {  data,  error,  isError,  isFetching,  isLoading,  isRefetching,  isSuccess,  refetch,} = useQuery(queryKey, queryFn?, {  enabled,  onError,  onSuccess,  refetchOnWindowFocus,  retry,  staleTime,})

如果我们把这些 API 简化如下:0jX28资讯网——每日最新资讯28at.com

const {  ...result,} = useQuery(queryKey, queryFn?, {  ...options,})

useInfiniteQuery() 其实就是在 useQuery() 基础之上增添一些无限查询场景的参数:0jX28资讯网——每日最新资讯28at.com

const {  fetchNextPage,  fetchPreviousPage,  hasNextPage,  hasPreviousPage,  isFetchingNextPage,  isFetchingPreviousPage,  ...result} = useInfiniteQuery(queryKey, ({ pageParam = 1 }) => fetchPage(pageParam), {  ...options,  getNextPageParam: (lastPage, allPages) => lastPage.nextCursor,  getPreviousPageParam: (firstPage, allPages) => firstPage.prevCursor,})

如你所见,增加的 API 其实就是跟上一页/下一页查询动作相关的参数,相比较于自己组装 的分页查询能力的 useQuery(),useInfiniteQuery() 需要配置上一页/下一页的参数获取函数,并提供了相应的查询调用能力,更加自动化和便捷。0jX28资讯网——每日最新资讯28at.com

当然,增加的不只是参数,还有 2 处:0jX28资讯网——每日最新资讯28at.com

一个是 queryFn 参数的入参,多了一个名为 pageParam 的参数。0jX28资讯网——每日最新资讯28at.com

pageParam 表示当前页数。这个值是每次 useInfiniteQuery() 调用时,通过 getNextPageParam()/getPreviousPageParam() 返回值自动获取并传入 queryFn 的。0jX28资讯网——每日最新资讯28at.com

第二个还有返回值的数据结构,即 data。0jX28资讯网——每日最新资讯28at.com

const { data } = useInfiniteQuery()

原来 data 就是表示内部请求方法的返回值。而 useInfiniteQuery() 的返回 data 因为要包含多页数据(展示旧数据时,还要持有旧数据),因此 data 变更为:0jX28资讯网——每日最新资讯28at.com

data: { pages: TData[], pageParams: unknown[] }

pages 很好理解,就是用来承载过程中请求到的多页数据;pageParams 则是每个页面当时在做数据获取时使用的查询参数。0jX28资讯网——每日最新资讯28at.com

简单一例

当然语言上说得再多,也是苍白无力的,实践出真知。这里我们就举一个简单的例子说明 useInfiniteQuery() 的使用。0jX28资讯网——每日最新资讯28at.com

首先,我们先创建一个获取数据的请求函数(使用 Fetch API)。0jX28资讯网——每日最新资讯28at.com

const getPosts = async (pageParam) => {  return fetch(`https://jsonplaceholder.typicode.com/posts?_page=${pageParam.page}&_limit=${pageParam.size}`).then(res => res.json())}

接着,使用 useInfiniteQuery() 请求数据:0jX28资讯网——每日最新资讯28at.com

function Example() {  const {    isLoading,    isError,    error,    data,  } = useInfiniteQuery(    'posts',    ({ pageParam }) => getPosts(pageParam),    {      getNextPageParam: (lastPage, allPages) => ({ page: allPages.length + 1, size: 6 }),      refetchOnWindowFocus: false, // Prevent refetching on window focus    }  )    // ...}

增加下加载中或出现异常时的处理逻辑。0jX28资讯网——每日最新资讯28at.com

function Example() {  // ...  if (isLoading) {    return <div>Loading...</div>;  }  if (isError) {    return <div>Error: {error.message}</div>  }    // ...}

最后渲染分页数据。0jX28资讯网——每日最新资讯28at.com

function Example() {  // ...  return (    <div>      <ol>        {/* (1) */}        {data.pages.map((page) => (          {page.map((post) => (            <li key={post.id}>{post.title}</li>          ))}        ))}      </ol>            {/* (2) */}      <button onClick={() => fetchNextPage()}>More</button>    </div>  )}
  1. 遍历 data.pages 中所有页面数据,渲染出来
  2. 使用 fetchNextPage() 函数加载更多(实际上即“下一页”)数据

浏览器访问,不幸运是,报错了。0jX28资讯网——每日最新资讯28at.com

图片图片0jX28资讯网——每日最新资讯28at.com

完美。0jX28资讯网——每日最新资讯28at.com

最后,再把完整代码贴出来,方便大家学习。0jX28资讯网——每日最新资讯28at.com

import { useEffect, useRef } from 'react'import { QueryClient, QueryClientProvider, useInfiniteQuery } from 'react-query'// Create a clientconst queryClient = new QueryClient()export default function App() {  return (    // Provide the client to your App    <QueryClientProvider client={queryClient}>      <Example />    </QueryClientProvider>  )}const getPosts = async (pageParam = { page: 1, size: 25 }) => {  return fetch(`https://jsonplaceholder.typicode.com/posts?_page=${pageParam.page}&_limit=${pageParam.size}`).then(res => {    const total = res.headers.get('X-Total-Count')    return res.json().then(data => {      return {        total,        data,        hasMore: pageParam.page * pageParam.size < total      }    })  })}function Example() {  const {    isLoading,    isFetchingNextPage,    hasNextPage,    isError,    error,    data,    fetchNextPage  } = useInfiniteQuery(    'posts',    ({ pageParam }) => getPosts(pageParam),    {      getNextPageParam: (lastPage, allPages) => {        return lastPage.hasMore ? { page: allPages.length + 1, size: 25 } : undefined      },      refetchOnWindowFocus: false, // Prevent refetching on window focus    }  )  const loadMoreRef = useRef(null);  useEffect(() => {    const observer = new IntersectionObserver((entries) => {      if (entries[0].isIntersecting && hasNextPage) {        fetchNextPage();      }    });    if (loadMoreRef.current) {      observer.observe(loadMoreRef.current);    }    return () => observer.disconnect();  }, [hasNextPage, fetchNextPage]);  if (isLoading) {    return <div>Loading...</div>;  }  if (isError) {    return <div>Error: {error.message}</div>  }  return (    <div>      <p>总共 <strong>{data.pages[0].total}</strong> 条数据</p>      <ol>        {data.pages.map((page) => (          <>            {page.data.map((post) => (              <li key={post.id}>{post.title}</li>            ))}          </>        ))}      </ol>      <div className="loadMore" style={{ height: '30px', lineHeight: '30px' }} ref={loadMoreRef}>        {          isFetchingNextPage ? <span>Loading...</span> : <span>--- 我是有底线的 ---</span>        }      </div>    </div>  )}

总结

本文我们讲述了 React Query 中用于无限查询 API useInfiniteQuery() 的使用。0jX28资讯网——每日最新资讯28at.com

通过循序渐进的 3 个案例,最终实现了一个下拉到底后自动新数据的交互效果,还是比较好实现的。0jX28资讯网——每日最新资讯28at.com

当然,本文只是以“下一页”举例,“上一页”与此同理。0jX28资讯网——每日最新资讯28at.com

希望本位讲述的内容能够对你的工作有所帮助。感谢阅读,再见。0jX28资讯网——每日最新资讯28at.com

参考资料

[1]React Query 是做什么的?: https://juejin.cn/post/73780152133482578550jX28资讯网——每日最新资讯28at.com

[2]一个数据获竟然被 React Query 玩出这么多花样来!: https://juejin.cn/post/73803421605819187310jX28资讯网——每日最新资讯28at.com

[3]React Query 的 useQuery 竟也内置了分页查询支持!: https://juejin.cn/post/73805697756867461510jX28资讯网——每日最新资讯28at.com

[4]IntersectionObserver API: https://ruanyifeng.com/blog/2016/11/intersectionobserver_api.html0jX28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-98195-0.html如何使用 React Query 做下拉数据自动刷新?

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 聊聊大文件分片上传和分片下载

下一篇: 智能个性化推荐系统设计与实践,你学会了吗?

标签:
  • 热门焦点
  • 摸鱼心法第一章——和配置文件说拜拜

    摸鱼心法第一章——和配置文件说拜拜

    为了能摸鱼我们团队做了容器化,但是带来的问题是服务配置文件很麻烦,然后大家在群里进行了“亲切友好”的沟通图片图片图片图片对比就对比,简单对比下独立配置中心和k8s作为配
  • K8S | Service服务发现

    K8S | Service服务发现

    一、背景在微服务架构中,这里以开发环境「Dev」为基础来描述,在K8S集群中通常会开放:路由网关、注册中心、配置中心等相关服务,可以被集群外部访问;图片对于测试「Tes」环境或者
  • 三言两语说透设计模式的艺术-单例模式

    三言两语说透设计模式的艺术-单例模式

    写在前面单例模式是一种常用的软件设计模式,它所创建的对象只有一个实例,且该实例易于被外界访问。单例对象由于只有一个实例,所以它可以方便地被系统中的其他对象共享,从而减少
  • 如何正确使用:Has和:Nth-Last-Child

    如何正确使用:Has和:Nth-Last-Child

    我们可以用CSS检查,以了解一组元素的数量是否小于或等于一个数字。例如,一个拥有三个或更多子项的grid。你可能会想,为什么需要这样做呢?在某些情况下,一个组件或一个布局可能会
  • 三言两语说透柯里化和反柯里化

    三言两语说透柯里化和反柯里化

    JavaScript中的柯里化(Currying)和反柯里化(Uncurrying)是两种很有用的技术,可以帮助我们写出更加优雅、泛用的函数。本文将首先介绍柯里化和反柯里化的概念、实现原理和应用
  • 一文搞定Java NIO,以及各种奇葩流

    一文搞定Java NIO,以及各种奇葩流

    大家好,我是哪吒。很多朋友问我,如何才能学好IO流,对各种流的概念,云里雾里的,不求甚解。用到的时候,现百度,功能虽然实现了,但是为什么用这个?不知道。更别说效率问题了~下次再遇到,
  • 零售大模型“干中学”,攀爬数字化珠峰

    零售大模型“干中学”,攀爬数字化珠峰

    文/侯煜编辑/cc来源/华尔街科技眼对于绝大多数登山爱好者而言,攀爬珠穆朗玛峰可谓终极目标。攀登珠峰的商业路线有两条,一是尼泊尔境内的南坡路线,一是中国境内的北坡路线。相
  • 冯提莫签约抖音公会 前“斗鱼一姐”消失在直播间

    冯提莫签约抖音公会 前“斗鱼一姐”消失在直播间

    来源:直播观察提起&ldquo;冯提莫&rdquo;这个名字,很多网友或许听过,但应该不记得她是哪位主播了。其实,作为曾经的&ldquo;斗鱼一姐&rdquo;,冯提莫在游戏直播的年代影响力不输于现
  • 外交部:美方应停止在网络安全问题上不负责任地指责他国

    外交部:美方应停止在网络安全问题上不负责任地指责他国

      中国外交部今天(16日)举行例行记者会。会上,有记者问,美国情报官员称,他们正在阻拦来自中国以及其他国家的黑客获取相关科研成果。 中方对此有何评论?对此
Top