react-query

本文最后更新于:2023年12月5日 晚上

官网:https://tanstack.com/query/latest/docs/react/overview

刷新缓存:使用refetch或者使缓存失效,如果是全部查询则使用前者,如果是分页查询则使用后者。

staleTimecacheTime

  • staleTime:可以理解为数据保质期,在保质期内遇到同 key 的请求,不会去再次获取数据,而是从缓存中获取。

    staleTime 默认 0

  • cacheTime :数据在内存中的缓存时间,当数据在缓存期时,会按照 key 进行存储,下次遇到同 key 获取数据,会直接从缓存中取,瞬间展示,但是否后台请求新数据,要看 staleTime 的配置,当不配置 staleTime 时,遇到同 key 获取数据,虽然瞬间切换至缓存数据展示,但此时后台获取新数据,待获取完毕后瞬间切换为新数据。

    cacheTime 默认5分钟

https://blog.csdn.net/qq_21567385/article/details/114171438

isLoadingisFetching

  • isLoading
  • isFetching

isLoading 是在 “硬” 加载时才会为 trueisFetching 是在每次请求时为 true,那么 isFetching 我们能通俗易懂的理解,就是每次请求时当做 loading 嘛。

那什么是 isLoading 的 “硬” 加载?其实 “硬” 加载就是没有缓存时的加载,那么缓存是什么?

Query Invalidation(查询失效)

QueryClientinvalidateQueries 方法主动让查询(query)失效。

// 让缓存中的所有查询失效
queryClient.invalidateQueries()
// 使用'todos'开头的键的查询都失效
queryClient.invalidateQueries({ queryKey: ['todos'] })

当使用invalidateQueries让一个查询失效时,会发生两件事:

  • 查询被标记为过期(stale),过期状态会覆盖staleTime配置。
  • 发起重新请求(refetch),如果当前页面正渲染查询的数据,也会重新请求。

查询匹配

使用invalidateQueriesremoveQueries这些API(支持查询配置的都可以),支持精确匹配,也可以通过前缀匹配多个查询。

关于过滤器的类型,参考Query Filters.

下面示例中,使用todos前缀使查询键中以todos开头的所有查询失效:

import { useQuery, useQueryClient } from '@tanstack/react-query'

// Get QueryClient from the context
const queryClient = useQueryClient()

queryClient.invalidateQueries({ queryKey: ['todos'] })

// Both queries below will be invalidated
const todoListQuery = useQuery({
  queryKey: ['todos'],
  queryFn: fetchTodoList,
})
const todoListQuery = useQuery({
  queryKey: ['todos', { page: 1 }],
  queryFn: fetchTodoList,
})

传递具体的query key:

queryClient.invalidateQueries({
  queryKey: ['todos', { type: 'done' }],
})

// 会失效
const todoListQuery = useQuery({
  queryKey: ['todos', { type: 'done' }],
  queryFn: fetchTodoList,
})

// 不会失效
const todoListQuery = useQuery({
  queryKey: ['todos'],
  queryFn: fetchTodoList,
})

invalidateQueries API是非常灵活的,如果只想让todos查询失效,而不影响更多的子键,可以通过设置exact: true实现:

queryClient.invalidateQueries({
  queryKey: ['todos'],
  exact: true,    // 精确匹配,不会扩大范围
})

// 会失效
const todoListQuery = useQuery({
  queryKey: ['todos'],
  queryFn: fetchTodoList,
})

// 不会失效
const todoListQuery = useQuery({
  queryKey: ['todos', { type: 'done' }],
  queryFn: fetchTodoList,
})

如果要更精细的颗粒度,可以传入函数:

queryClient.invalidateQueries({
  predicate: (query) =>
    query.queryKey[0] === 'todos' && query.queryKey[1]?.version >= 10,  // version >= 10 返回true
})

// 会失效
const todoListQuery = useQuery({
  queryKey: ['todos', { version: 20 }],
  queryFn: fetchTodoList,
})

// 会失效
const todoListQuery = useQuery({
  queryKey: ['todos', { version: 10 }],
  queryFn: fetchTodoList,
})

// 不会失效
const todoListQuery = useQuery({
  queryKey: ['todos', { version: 5 }],
  queryFn: fetchTodoList,
})

react-query
http://blog.lujinkai.cn/前端/React/react-query/
作者
像方便面一样的男子
发布于
2022年1月25日
更新于
2023年12月5日
许可协议