【问题标题】:Proper way to call RTK Query endpoint.select() with no arguments (and skip options)不带参数(和跳过选项)调用 RTK Query endpoint.select() 的正确方法
【发布时间】: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() 时,需要一个指示参数的打字稿警告表面。

【问题讨论】:

    标签: react-hooks react-query rtk-query


    【解决方案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 并且没有任何参数被认为是相等的
    猜你喜欢
    • 1970-01-01
    • 2021-11-04
    • 1970-01-01
    • 2022-06-12
    • 2022-01-17
    • 2021-09-10
    • 2016-12-01
    • 2011-01-26
    • 1970-01-01
    相关资源
    最近更新 更多