如何从与参数的查询中从适配器中提取选择器

发布于 2025-01-22 15:32:23 字数 1875 浏览 1 评论 0原文

正如本文档中所述: https://redux.js.org/tutorials/essentials/part-8-rtk-query-advanced

文档提出了此示例:


const usersAdapter = createEntityAdapter()

const initialState = usersAdapter.getInitialState()

export const extendedApiSlice = apiSlice.injectEndpoints({
  endpoints: builder => ({
    getUsers: builder.query({
      query: () => '/users',
      transformResponse: responseData => {
        return usersAdapter.setAll(initialState, responseData)
      }
    })
  })
})

export const { useGetUsersQuery } = extendedApiSlice

// Calling `someEndpoint.select(someArg)` generates a new selector that will return
// the query result object for a query with those parameters.
// To generate a selector for a specific query argument, call `select(theQueryArg)`.
**// In this case, the users query has no params, so we don't pass anything to select()**
export const selectUsersResult = extendedApiSlice.endpoints.getUsers.select()

const selectUsersData = createSelector(
  selectUsersResult,
  usersResult => usersResult.data
)

export const { selectAll: selectAllUsers, selectById: selectUserById } =
  usersAdapter.getSelectors(state => selectUsersData(state) ?? initialState)

现在,我需要拥有 selectbyid 选择器(默认情况下,将用户ID作为第二个参数)。 当我的查询看起来像这样时,我无法设法让工作 selectbyid 选择器

endpoints: builder => ({
    getUsers: builder.query({
      query: (applicationId) => `/application/${applicationId}/users`,
      transformResponse: responseData => {
        return usersAdapter.setAll(initialState, responseData)
      }
    })
  })

如何从适配器提取 selectbyid 从适配器提取 selector,以及我如何在使用use -lector的组件中使用它我有这样的疑问吗?

谢谢任何会帮助我的人

I'm trying to extract selectors from queries in my apiSlice as said in this documentation: https://redux.js.org/tutorials/essentials/part-8-rtk-query-advanced

The documentation put this example:


const usersAdapter = createEntityAdapter()

const initialState = usersAdapter.getInitialState()

export const extendedApiSlice = apiSlice.injectEndpoints({
  endpoints: builder => ({
    getUsers: builder.query({
      query: () => '/users',
      transformResponse: responseData => {
        return usersAdapter.setAll(initialState, responseData)
      }
    })
  })
})

export const { useGetUsersQuery } = extendedApiSlice

// Calling `someEndpoint.select(someArg)` generates a new selector that will return
// the query result object for a query with those parameters.
// To generate a selector for a specific query argument, call `select(theQueryArg)`.
**// In this case, the users query has no params, so we don't pass anything to select()**
export const selectUsersResult = extendedApiSlice.endpoints.getUsers.select()

const selectUsersData = createSelector(
  selectUsersResult,
  usersResult => usersResult.data
)

export const { selectAll: selectAllUsers, selectById: selectUserById } =
  usersAdapter.getSelectors(state => selectUsersData(state) ?? initialState)

Now, i need to have selectById selector (that by default takes userid as second parameter).
I can't manage to have a working selectById selector when my query looks like this

endpoints: builder => ({
    getUsers: builder.query({
      query: (applicationId) => `/application/${applicationId}/users`,
      transformResponse: responseData => {
        return usersAdapter.setAll(initialState, responseData)
      }
    })
  })

How do I extract selectById selector from adapter and how i use it in a component with useSelector when I have this kind of query with arguments?

Thanks anyone that will help me

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

禾厶谷欠 2025-01-29 15:32:23

我觉得您不匹配的概念有些不匹配,因此会导致混乱。

首先,让我们澄清一下,这是您使用的选择 - 它不是usersAdapter的选择者,而是RTK-Q自己的状态。
通过在变形金刚中处理响应,您只是将数据复制到您的数据中,usersAdapter的状态。

因此,考虑到您应该从哪种状态中进行选择。如果您需要从“最终目标”中,即从适配器的状态中进行IE,则应通过:

const usersSelectors = **usersAdapter**.getSelectors(
  (state) => state.users // or something like that
)

否则,使用extendedApislice从示例中使用诸如extendedApislice的选择器 - 您正在从RTK获取数据-Q的缓存状态,该状态可能不包含缓存无效后的一些旧数据。如果您仍然是您的目标,那么限制是RTK-Q的商店不是您可能期望的标准化商店,具有ID和值,而是键值对,键是您的请求,而值 - 值 - 最后结果(最后结果(用户数组在您的情况下)。因此,如果未定义用于选择特定用户ID的API端点,则将无法直接从RTK-Q的状态中选择它。但是您可以通过applicationId选择缓存的用户,并在结果数组中通过ID找到您的用户。我敢打赌,这不是您真正想要的,因此,如上所述,您很可能只需要为自己的商店准备选择器。

I feel like you mismatch concepts a bit, so it leads to confusion.

First of all, let's clarify, that's selectors you a using- it's not a selector to your state in usersAdapter, but to RTK-Q's own state.
By handling a response in transformResponse you are just copying the data from it to your's, usersAdapter's state.

So, considering that, you should be specific about which state you are going to select from. If you want it from the "final destination", i.e. from the adaptor's state, it's should be done via:

const usersSelectors = **usersAdapter**.getSelectors(
  (state) => state.users // or something like that
)

Otherwise, using the selectors from apiSlices like extendedApiSlice from your example - you are fetching the data from RTK-Q's cached state, which may not contain some old data after the cache invalidation. If it's still your goal, the limitation is that RTK-Q's store isn't a normalized store you may expect, with ids and values, but rather the key-value pairs, where keys are your requests, and the values - last results (users arrays in your case). So, if you have no API endpoint defined for selecting a particular user by ID, you won't be able to select it from RTK-Q's state directly. But you may select the cached users by applicationId, and find your user by id in the result array. I bet it's not what you actually want, so most probably you need just to prepare selectors for your own store, as I've mentioned above.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文