国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

如何將 RTK 查詢與選擇器結(jié)合使用
P粉729198207
P粉729198207 2023-12-28 11:46:38
0
1
989

我正在使用 Redux ToolkitRTK 查詢 建立一個(gè)項(xiàng)目,並嘗試從 API 取得一些條目。我正在使用 createEntityAdapter 的規(guī)範(fàn)化資料方法,因?yàn)樵谀硞€(gè)元件中我需要將資料作為數(shù)組,所以我最終使用了選擇器?,F(xiàn)在我的問題是,由於我添加過濾器作為查詢的參數(shù),我的選擇器停止工作。

我在這裡研究了類似的問題,例如:“如何使用帶有參數(shù)的 RTK 查詢選擇器?”,但我太笨了,無法理解我應(yīng)該修改的內(nèi)容。我試圖理解 RTK 查詢文檔,但我做不到。

從上面的問題中,我知道我的選擇器還需要具有參數(shù),以便準(zhǔn)確地知道要選擇什麼,並且這不是推薦的模式,但我無法理解如何使其工作。

我的條目切片:

import { createSelector, createEntityAdapter } from '@reduxjs/toolkit'
import { apiSlice } from './apiSlice'

const entryAdapter = createEntityAdapter()

const initialState = entryAdapter.getInitialState({
  ids: [],
  entities: {},
})

export const entryApiSlice = apiSlice.injectEndpoints({
  endpoints: (builder) => ({
    initialState,
    getEntry: builder.query({
      query: (filters) => ({
        url: '/history',
        params: filters,
      }),
      transformResponse: (responseData) => {
        return entryAdapter.setAll(initialState, responseData)
      },
      providesTags: (result, error, arg) => [
        { type: 'Entry', id: 'LIST' },
        ...result.ids.map((id) => ({ type: 'Entry', id })),
      ],
    }),
    addEntry: builder.mutation({
      query: (data) => ({
        url: '/history/new',
        method: 'POST',
        body: data,
      }),
      invalidatesTags: [{ type: 'Entry', id: 'LIST' }],
    }),
    updateEntry: builder.mutation({
      query: (initialEntry) => ({
        url: `/history/${initialEntry.Id}`,
        method: 'PUT',
        body: {
          ...initialEntry,
          date: new Date().toISOString(),
        },
      }),
      invalidatesTags: (result, error, arg) => [{ type: 'Entry', id: arg.id }],
    }),
    deleteEntry: builder.mutation({
      query: ({ id }) => ({
        url: `/history/${id}`,
        method: 'DELETE',
        body: { id },
      }),
      invalidatesTags: (result, error, arg) => [{ type: 'Entry', id: arg.id }],
    }),
  }),
})

export const {
  useGetEntryQuery,
  useAddEntryMutation,
  useUpdateEntryMutation,
  useDeleteEntryMutation,
} = entryApiSlice

export const selectEntryResult = (state, params) =>
  entryApiSlice.endpoints.getEntry.select(params)(state).data

const entrySelectors = entryAdapter.getSelectors(
  (state) => selectEntryResult(state) ?? initialState
)
export const selectEntry = entrySelectors.selectAll

我在像這樣的 Entries 元件中使用它

const {
    data: entriesData = [],
    refetch,
    isLoading,
    isSuccess,
    isError,
    error,
  } = useGetEntryQuery(filters)

  const entries = useSelector(selectEntry)

注意:如果我從獲取查詢中刪除“過濾器”,一切都會(huì)像以前一樣工作(當(dāng)然,正如預(yù)期的那樣)。

免責(zé)聲明:我不知道我到底在做什麼,我已經(jīng)閱讀了文件並且正在嘗試弄清楚,所以我非常感謝任何反饋。 謝謝!

P粉729198207
P粉729198207

全部回覆(1)
P粉779565855

是的,這是一個(gè)有點(diǎn)敏感的話題,因?yàn)?RTKQ 的文件傾向於顯示最簡(jiǎn)單的範(fàn)例,即完全不使用任何參數(shù)的查詢。我自己也遇到過很多問題。

無論如何,您已將 selectEntryResult 宣告為兩個(gè)參數(shù)的函數(shù):state 和 params。然後,當(dāng)您在其下方建立適配器選擇器時(shí),您僅使用一個(gè)參數(shù)來呼叫它:狀態(tài)。此外,當(dāng)您在元件中使用最終選擇器時(shí),如下所示:

const entries = useSelector(selectEntry);

參數(shù)無處可尋,預(yù)設(shè)情況下它們未定義,無法找到與此類查詢參數(shù)關(guān)聯(lián)的任何資料。

這裡要理解的關(guān)鍵是,您實(shí)際上需要以某種方式透過選擇器的每個(gè)層級(jí)(每個(gè)包裝器)傳遞查詢參數(shù)。

這裡的一種方法是透過選擇器「轉(zhuǎn)發(fā)」參數(shù):

export const selectEntryResult = createSelector([state => state, (_, params) => params], (state, params) =>
  entryApiSlice.endpoints.getEntry.select(params)(state)?.data ?? initialState)

這裡我們使用從RTK匯出的createSelector函數(shù)。然後在你的元件中你會(huì)做這樣的事情:

  const {...} = useGetEntryQuery(filters);

  const entries = useSelector(state => selectEntry(state, filters));

這在使用實(shí)體適配器建立的 selectAll 選擇器時(shí)有效,但在使用 selectById 時(shí)會(huì)導(dǎo)致問題,因?yàn)樵撨x擇器也是參數(shù)化的。簡(jiǎn)而言之,selectById 選擇器在內(nèi)部定義為使用您希望檢索的實(shí)體id 的第二個(gè)參數(shù),而我展示的方法使用第二個(gè)參數(shù)來傳遞查詢參數(shù)(您的篩選器中的過濾器)。案例)。

據(jù)我所知,到目前為止還沒有解決方案可以完美運(yùn)行並涵蓋以下所有內(nèi)容:

  • 使用實(shí)體規(guī)範(fàn)化
  • 使用選擇器檢索資料
  • 使用參數(shù)化查詢

另一種方法可能是建立一些選擇器工廠,這些選擇器工廠為查詢參數(shù)的特定組合動(dòng)態(tài)建立基本選擇器。

我曾經(jīng)製作過這樣一個(gè)包裝器,可以在所有情況下使用。不幸的是,我無法共享它,因?yàn)樗且粋€(gè)私有包,但基本思想是改變參數(shù),以便selectByIdselectAll (以及所有其他選擇器)都可以正常工作,透過將查詢參數(shù)作為第三個(gè)參數(shù)傳遞給選擇器,然後進(jìn)一步重新包裝每個(gè)實(shí)體適配器選擇器:

export const createBaseSelector = (endpoint) =>
  createSelector(
    [(state) => state, (_, other) => other, (_, _other, params) => params],
    (state, _other, params) => endpoint.select(params)(state)
  );

const selectors = adapter.getSelectors(baseSelector);

// And then rewrap selectAll and selectById from 'selectors' above

我知道這聽起來很複雜,我?guī)缀鯖]有讓它工作,所以盡量避免朝這個(gè)方向走:)

可以找到我一路上找到的一篇有用的文章這裡,他們還描述了一些在組件級(jí)別創(chuàng)建選擇器並記住它們的方法,但我還沒有全部嘗試過??纯窗?,也許您會(huì)找到更簡(jiǎn)單的方法來解決您的特定問題。

最新下載
更多>
網(wǎng)站特效
網(wǎng)站源碼
網(wǎng)站素材
前端模板