不带参数(和跳过选项)调用 RTK Query endpoint.select() 的正确方法
Posted
技术标签:
【中文标题】不带参数(和跳过选项)调用 RTK Query endpoint.select() 的正确方法【英文标题】:Proper way to call RTK Query endpoint.select() with no arguments (and skip options) 【发布时间】:2022-01-21 16:46:15 【问题描述】:我想使用endpoint.select()
函数从缓存的RTK Query 数据中创建选择器,请参阅RTK Advanced Patterns。
文档明确指出,如果没有查询参数,您可以将 undefined 传递给select()
(请参阅选择用户数据部分)。
但是,在我的情况下,除非我通过 initiate() 函数触发查询,否则这不起作用。另一方面,当从查询挂钩触发查询时,选择器无法检索缓存数据。
这里的不工作设置非常简单:
export const productsApi = createApi(
baseQuery: fetchBaseQuery( baseUrl: API.ENDPOINTS.PRODUCTS ),
reducerPath: 'productsApi',
endpoints: (builder) => (
listAllProducts: builder.query(
query: ()=>'/list',
),
),
);
export const useListAllProductsQuery = productsApi;
然后在 customHook 中我调用 useListAllProducts 钩子:
const
data,
= useListAllProductsQuery(skip:shouldSkip);
最后在选择器中:
export const selectProducts =
productsApi.endpoints.listAllProducts.select(); //undefined param as docs recommend
潜在的修复:(或者更像是一个 hacky 解决方法): 奇怪的是,我发现如果我将一个参数(又名 cacheKey)传递给 select 函数并将相同的 cacheKey 传递给查询钩子,突然之间星星对齐并且一切正常(尽管文档声明这不是必需的)。所以修改后的代码如下:
// in selector
export const selectProducts =
productsApi.endpoints.listAllProducts.select('products');
// in hook
const
data,
= useListAllProductsQuery('products');
我想知道是否有人可以就其工作原理提供一些智慧,或者更好的是 推荐在没有 cacheKey 的查询上使用 select 函数的最佳实践(因为文档似乎不正确或过时?)。
我还想指出,在没有参数的情况下调用select()
时,需要一个指示参数的打字稿警告表面。
【问题讨论】:
【参考方案1】:我不确定您认为文档在哪里声明您不需要参数。
你需要调用select
,使用与调用钩子时相同的参数获取该缓存键的选择器 - 所以如果你调用useMyQuery()
,你可以调用select()
- 如果你调用useMyQuery(5)
,你可以调用select(5)
来获取缓存键5
的选择器。
这些是单独的缓存条目,您需要为每个缓存条目选择一个选择器。
另外,您能否澄清一下“不工作”的确切含义?使用选择器只会为您提供缓存条目,但不会发出请求 - 毕竟您只是从商店中选择。所以在你使用钩子或调度initiate
之前,你会得到一个uninitiated
缓存条目。
【讨论】:
文档在多个位置声明它(特别是没有参数的查询)。请参阅我引用的“选择用户数据”部分。在我的示例中,我没有 cacheKey,所以我只是调用了不起作用的 select()。我所说的不工作的意思是选择器无法从缓存中返回任何数据。 因此在您的示例中,useMyQuery()
需要变为 useMyQuery('someDummyKey')
并选择(someDummyKey
)。在我进行此更改的那一刻,它按预期工作。
如果这是真的,那将是一个错误 - 但老实说,这不太可能,因为useMyQuery()
也只是在内部调用select()
以获得完全相同的选择器。所以我想会有其他事情发生。你能创建一个显示这种行为的 CodeSandbox 吗?
另外,它似乎永远不会返回任何东西 - 它至少应该返回 status: "uninitialized", isUninitialized: true, is...: false
选项必须始终是第二个参数,因此如果您想使用skip
而不是skipToken
,则必须调用useMyQuery(undefined, skip: true )
。使用undefined
作为参数将与select()
调用一起使用,undefined
并且没有任何参数被认为是相等的以上是关于不带参数(和跳过选项)调用 RTK Query endpoint.select() 的正确方法的主要内容,如果未能解决你的问题,请参考以下文章
如果我使用 Redux Toolkit 和 RTK-Query,需要 thunk 吗?
RTK Query 使用 getState() 从另一个切片获取状态