React Query 学习 6 React Query 内部实
2022-12-11 本文已影响0人
吴摩西
QueryClient
Query Clientimport { QueryClient, QueryClientProvider } from '@tanstack/react-query'
// ⬇️ this creates the client
const queryClient = new QueryClient()
function App() {
return (
// ⬇️ this distributes the client
<QueryClientProvider client={queryClient}>
<RestOfYourApp />
</QueryClientProvider>
)
}
- QueryClient 应该只创建一次。使用 Context 复用。这个值不会变化,不会引起 client 重绘。只为了在组件中使用
useQuery
获取这个 client 的引用。 - QueryClient 中做的事情很少,初始化后,只自动初始化了
QueryCache
和MutationCache
。
QueryCache 只默认在内存中进行缓存。可以通过
persistOptions
进行其他类型的缓存。
import { PersistQueryClientProvider } from '@tanstack/react-query-persist-client'
import { createSyncStoragePersister } from '@tanstack/query-sync-storage-persister'
const queryClient = new QueryClient({
defaultOptions: {
queries: {
cacheTime: 1000 * 60 * 60 * 24, // 24 hours
},
},
})
const persister = createSyncStoragePersister({
storage: window.localStorage,
})
ReactDOM.createRoot(rootElement).render(
<PersistQueryClientProvider
client={queryClient}
persistOptions={{ persister }}
>
<App />
</PersistQueryClientProvider>
)
Query
QueryQuery 中包含:数据,状态,其他的元数据,例如上一次查询时间。它负责执行查询函数,重试,取消查询以及去掉重复查询(de-duplication)的逻辑。
Query 中包含一个状态机,当一个查询正在执行,又触发了同样的查询,后续的查询会被去掉(de-duplication)。如果一个查询被取消,它会被重置到上一个状态。
QueryObserver
QueryObserverQueryObserver 把 Query 和 组件粘合在一起。useQuery
调用时,会被自动创建。它会精确的跟踪此查询。Observer 能精确的知道组件用到了数据的那些属性。只有这些使用的属性变化时,才会通知组件重新渲染。Observer 支持 select 选项,可以精确的控制究竟监听哪些属性的变化。自动查询,以及 staleTime
相关的逻辑也在 QueryObserver 中。
活跃和不活跃的查询
没有 Observer
的 Query
被认为不活跃的查询。它还在缓存中,只是不在被任何组件使用。
整体架构
whole picture上图是从 React Query 的视角看的架构。从组件视角看来:
component view
- 组件挂载时,调用
useQuery
创建对应的Observer
-
Observer
订阅了Query
,Query
都在QueryCache
中 - 调用查询时,如果没有可复用的,就会创建 Query,如果有 Query,并且数据已经陈旧,就会触发重新获取数据。
- 获取数据时,会修改 Query 的状态。
Observer
就会被通知。 -
Observer
会执行一些优化,可能会通知组件相关的更新。组件会渲染新的状态。 -
Query
执行完成后,它会通知Observer
。
理想情况下,通过数据的预取,当组件挂载时,数据已经在缓存中,就无需等待了。