专栏目录: 全网最细 React-Query源码探秘 - 不月阳九的专栏 - 掘金 (juejin.cn)
QueryClient是React-Query的上层类,一般开发者不会直接访问Query对象,而是通过QueryClient类或者useQuery钩子去进行访问。
我们来看一下官网的使用说明
我们需要将client通过context的Provider共享给App下所有的组件才能正常使用React-Query
const client = new QueryClient()
return (
<QueryClientProvider client={client}>
<App/>
</QueryClientProvider>
)
源码中QueryClient通过React.context进行管理 让其可以被分发
const queryClient = React.useContext(
getQueryClientContext(React.useContext(QueryClientSharingContext))
)
源码解析
QueryClient提供了三种请求
fetch请求
prefetchQuery预请求
在useQuery使用数据之前,提前获取想要的数据,当真正用数据时,就可以从QueryCache获取缓存的Query对象上的数据
invalidateQueries主动失效
当开发者已明确知道Query data已经变更(不是新鲜的),可以调用invalidateQueries让对应的Query变成失效状态,同时重新请求网络数据
export class QueryClient {
constructor(){...}
// fetchQuery方法 会创建/找到一个Query,判断数据是否在新鲜时间内(isStale)
// 如果数据不新鲜调用query.fetch方法,发起网络请求
// 如果数据新鲜,则直接返回Query上的缓存数据
fetchQuery(options){
...
const query = this.queryCache.build(this, defaultedOptions)
return query.isStaleByTime(defaultedOptions.staleTime)
? query.fetch(defaultedOptions)
: Promise.resolve(query.state.data)
}
// 实际上调用的是 fetchQuery
// 但是之后使用noop(空函数)进行处理 不会抛出错误也不会刷新页面
// 用户使用的时候才会正常获取数据
preFetchQuery(){
...
return this.fetchQuery(arg1 as any, arg2 as any, arg3)
.then(noop)
.catch(noop)
}
// 将cache中的所有Query都invalidate失效
// 之后重新refetchQueries
invalidateQuery(){
...
this.queryCache.findAll(filters).forEach((query) => {
query.invalidate()
})
return this.refetchQueries(refetchFilters, options)
}
}