不使用 React Hooks 的使用方法
就像 Redux 核心和 Redux Toolkit 一样,RTK Query 的主要功能是 UI-agnostic,可以与任何 UI 层一起使用。RTK Query 还包括一个专为 React 设计的 createApi
版本,它自动生成 React hooks。
虽然 React hooks 是大多数用户预期使用 RTK Query 的主要方式,但该库本身使用纯 JS 逻辑,既可以与 React Class 组件一起使用,也可以独立于 React 本身使用。
本页面记录了在不使用 React Hooks 的情况下如何与 RTK Query 交互,以便正确使用 RTK Query 的 缓存行为
。
添加订阅
缓存订阅用于告诉 RTK Query 它需要为端点获取数据。可以通过分派附加到查询端点的 initiate
thunk action 创建器的结果来添加端点的订阅。
在 React hooks 中,这种行为是在 useQuery
、useQuerySubscription
、useLazyQuery
和 useLazyQuerySubscription
中处理的。
const promise = dispatch(api.endpoints.getPosts.initiate())
const { refetch } = promise
// 与 useFetch...() hook 一样与缓存交互
const { data, isLoading, isSuccess /*...*/ } = await promise
移除订阅
移除缓存订阅对于 RTK Query 确定不再需要缓存数据是必要的。这允许 RTK Query 清理和移除旧的缓存数据。
分派查询端点的 initiate
thunk action 创建器的结果是一个带有 unsubscribe
属性的 Promise。当调用此属性时,它将移除相应的缓存订阅。
在 React hooks 中,这种行为是在 useQuery
、useQuerySubscription
、useLazyQuery
和 useLazyQuerySubscription
中处理的。
// 添加缓存订阅
const promise = dispatch(api.endpoints.getPosts.initiate())
// 移除相应的缓存订阅
promise.unsubscribe()
访问缓存数据和请求状态
可以使用查询端点的 select
函数属性创建一个选择器,并用 Redux 状态调用它,以访问缓存数据和请求状态信息。这提供了在调用时的缓存数据和请求状态信息的快照。
endpoint.select(arg)
函数创建一个 新的 选择器实例 - 它不是实际的选择器函数本身!
在 React hooks 中,这种行为是在 useQuery
、useQueryState
和 useLazyQuery
中处理的。
const result = api.endpoints.getPosts.select()(state)
const { data, isSuccess, isError, error } = result
请注意,与自动生成的 hooks 不同,没有 isFetching
标志,如果状态是 pending,无论是否已经有数据,isLoading
标志都会为 true。
Memoization(记忆化)
由于 endpoint.select(arg)
函数每次调用时都返回一个新的选择器,并且这个实例本身是记忆化的,所以可能希望记忆化选择器的创建(例如,然后在另一个选择器中使用该记忆化实例)。这可以通过 createSelector
来完成:
const createGetPostSelector = createSelector(
(id: string) => id,
(id) => api.endpoints.getPost.select(id),
)
const selectGetPostError = createSelector(
(state: RootState) => state,
(state: RootState, id: string) => createGetPostSelector(id),
(state, selectGetPost) => selectGetPost(state).error,
)
执行变更
变更用于更新服务器上的数据。可以通过分派附加到变更端点的 initiate
thunk action 创建器的结果来执行变更。
在 React hooks 中,这种行为是在 useMutation
中处理的。
dispatch(api.endpoints.addPost.initiate({ name: 'foo' }))
示例
以下是不使用 React hooks 的使用示例:
React Class Components
示例中的PostDetail
组件Svelte
示例- 下面的
Cache Lifetime Subscription Class Component
示例:
更多信息
- NgRx 维护者 Brandon Roberts 写了一篇名为 Cousins playing nicely: Experimenting with NgRx Store and RTK Query 的文章,演示了一些将 RTK Query 集成到 NgRx 的方法
saulmoro/ngrx-rtk-query
实现了 RTKQ 自己的 React hooks 中管理的订阅生命周期的 NgRx 等价物