【问题标题】:Question about creating a API with redux-toolkit with react-query关于使用带有 react-query 的 redux-toolkit 创建 API 的问题
【发布时间】:2023-01-18 13:45:22
【问题描述】:

这更像是一个问题而不是一个问题。对编码和 redux-toolkit 非常陌生,我构建了一个 api,可以从服务器获取一堆项目。根据文档,这应该是一个简单的交易。

创建 api,获取钩子,钩子将为您提供在组件中使用的属性。像这样的东西。

  const {
    data: items, 
    isError,
    isLoading,
    isSuccess,
  } = useGetTravelItemsQuery();

但是,根据在线文档和一些教程,他们建议使用createEntityAdapter() 进行一些重新响应的排序。这需要额外的代码:

const travelItemsAdapter = createEntityAdapter<travelItem>({
  sortComparer: (a, b) => {
    let x = a.country.toLowerCase();
    let y = b.country.toLowerCase();
    if (x < y) {
      return -1;
    }
    if (x > y) {
      return 1;
    }
    return 0;
  },
});

这需要创建一个初始状态,以便您可以使用 getInitialState() 方法生成它。除此之外,您还必须形式化状态并将其返回到transformresponse 和 provideTags 中,以便在“更新、删除等”时间无效时重新获取数据。几个问题。

API 状态是否已经知道您创建的 tagTypes 是否发生了某些变化?我觉得这里有很多样板。然后响应被分成两个实体和 id,由于打字,我不知道如何在组件中使用它。请参阅下面的完整 API:

const baseURL = URL;

export const getItemsReqApi = createApi({
  reducerPath: "getItemsApi",
  baseQuery: fetchBaseQuery({ baseUrl: baseURL }),
  tagTypes: ["travelItems"],
  endpoints: (builder) => ({}),
});
const initialState = travelItemsAdapter.getInitialState();

export const extendedItemsSlice = getItemsReqApi.injectEndpoints({
  endpoints: (builder) => ({
    getTravelItems: builder.query<EntityState<travelItem>, void>({
      query: () => "items.json",
      transformResponse: (rawResults: travelItem[]) => {
        const fetchedItems: travelItem[] = [];
        for (let item in rawResults) {
          fetchedItems.push({
            ...rawResults[item],
            id: item,
          });
        }
        return travelItemsAdapter.setAll(initialState, fetchedItems);
      },
      providesTags: (res) =>
        res?.ids
          ? [
              ...res.ids.map((id) => ({ type: "travelItems" as const, id })),
              { type: "travelItems", id: "travelList" },
            ]
          : [{ type: "travelItems", id: "listTravelItems" }],
    }),
  }),
});

export const selectTravelItemsResponse =
  extendedItemsSlice.endpoints.getTravelItems.select();

export const selectTravelItemsData = createSelector(
  selectTravelItemsResponse,
  (travelItemsResponse) => travelItemsResponse.data
);

export const { useGetTravelItemsQuery } = extendedItemsSlice;

export const { selectAll: selectAllTravelItems } =
  travelItemsAdapter.getSelectors(
    (state: RootState) => selectTravelItemsData(state) ?? initialState
  );

我确实看到了使用 redux-toolkit 的好处,但我认为我要去一个兔子洞,因为我学到了很多东西。以上是处理请求和 API 创建的良好做法吗?

【问题讨论】:

    标签: reactjs redux react-redux redux-toolkit


    【解决方案1】:

    唔。我是 Redux 维护者,我认为你把事情搞得太复杂了 :)

    我假设您指的是我写的 https://redux.js.org/tutorials/essentials/part-8-rtk-query-advanced#transforming-responses

    RTK Query 是一个“文件缓存”式的工具。这意味着默认情况下它只是保存服务器返回的任何数据,格式完全一样。如果服务器响应是一个数组,它会保存该数组。如果服务器返回一个对象,它会保存该对象。

    如果你想将服务器发送的数据转换成不同的结构并保存,是的,你可以使用transformResponse来这样做。它可以使用 createEntityAdapter 将接收到的数组转换为规范化查找表并缓存该规范化值。

    但是,这完全是选修的而不是你需要一直做的事情。此外,“Essentials”教程的重点是向您介绍许多不同的东西。能够用 Redux Toolkit 做,但那个例子并不是想说你总是那样做。

    如果服务器向您发送一个数组,而您在这里要做的就是确保它已排序,您有几个选择:

    • transformResponse中排序然后返回
    • 在组件中进行排序

    这些都不需要使用createEntityAdapter

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-01-15
      • 2021-11-26
      • 2022-11-28
      • 2021-07-19
      • 2022-09-25
      • 2022-12-24
      • 2021-12-28
      • 2021-05-24
      相关资源
      最近更新 更多