如何在RTK查询中使标签 across-api 无效

huangapple go评论52阅读模式
英文:

How to invalidate tag across-api in RTK query

问题

I wanted to split the API into two parts, but the provided tag endpoint didn't refetch itself when the invalidatesTag endpoint at the other part was called.

BaseApi:

import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
export const baseApi = createApi({
  baseQuery: fetchBaseQuery({ baseUrl: `${import.meta.env.VITE_SERVER}` }),
  tagTypes: ["Cart", "Shopping", "Product"],
  endpoints: () => ({}),
});

CartApi:

import { baseApi } from "../BaseApi/baseApi";
type CartItemType = {
  product_id?: string;
  quantity?: number;
};
type CartType = {
  _id: string;
} & CartItemType;
type CartResponse = {
  message: string;
  data: CartType;
};

export const cartApi = baseApi.injectEndpoints({
  endpoints: (builder) => ({
    getCartByProDuctId: builder.query<CartResponse, string>({
      query: (id: string) => `cart-item/${id}`,
      providesTags: ["Cart"],
    }),
    createCart: builder.mutation<CartResponse, CartItemType>({
      query: (data: CartItemType) => ({
        url: "/cart-item/create",
        method: "PUT",
        body: data,
      }),
    }),
    updateCart: builder.mutation<CartResponse, CartItemType>({
      query: (data: CartItemType) => ({
        url: "/cart-item/update",
        method: "PATCH",
        body: data,
        invalidatesTags: ["Shopping"],
      }),
    }),
    deleteCart: builder.mutation<CartResponse, CartItemType>({
      query: (data: CartItemType) => ({
        url: "/cart-item/delete",
        method: "DELETE",
        body: data,
      }),
    }),
  }),
});
export const {
  useGetCartByProDuctIdQuery,
  useCreateCartMutation,
  useUpdateCartMutation,
  useDeleteCartMutation,
} = cartApi;

ShoppingApi:

import { baseApi } from "../BaseApi/baseApi";
import type { ProductType } from "../ProductReducer/ProductApi";
type cart_item = {
  product_id: ProductType;
  quantity: number;
};
type ShoppingSessionType = {
  cart_items: cart_item[];
  user_id?: string;
};
type shoppingType = {
  id: string;
  CartItemId: string;
};
export const shoppingApi = baseApi.injectEndpoints({
  endpoints: (builder) => ({
    getShoppingSession: builder.query<ShoppingSessionType, string>({
      query: (id: string) => `shopping/${id}`,
      providesTags: ["Shopping"],
    }),

    updateCartItem: builder.mutation<ShoppingSessionType, shoppingType>({
      query: ({ id, CartItemId }: shoppingType) => ({
        url: `shopping/update-cart-item/${id}`,
        method: "PATCH",
        body: { CartItemId },
      }),
      invalidatesTags: ["Shopping"],
    }),
    updateDeleteCartItem: builder.mutation<ShoppingSessionType, shoppingType>({
      query: ({ id, CartItemId }: shoppingType) => ({
        url: `shopping/update-delete/${id}`,
        method: "PATCH",
        body: { CartItemId },
      }),
    }),
  }),
});
export const {
  useGetShoppingSessionQuery,
  useUpdateCartItemMutation,
  useUpdateDeleteCartItemMutation,
} = shoppingApi;

My store setup:

import { configureStore } from "@reduxjs/toolkit";
import AuthReducer from "../api/AuthReducer/AuthReduce";
import { AuthMiddleware } from "../middleware/AuthMiddleware";
import { combineReducers } from "@reduxjs/toolkit";
import { setupListeners } from "@reduxjs/toolkit/dist/query";
import { userApi } from "../api/UserApi/UserApi";
import { productApi } from "../api/ProductReducer/ProductApi";
import { paymentUserApi } from "../api/UserApi/UserPaymentApi";
import { shoppingApi } from "../api/ShoppingSessionApi/ShoppingSessionApi";
import { cartApi } from "../api/CartReducer/CartApi";
import { baseApi } from "../api/BaseApi/baseApi";
import { ErrorLogger } from "../middleware/ErrorLogger";
const rootReducer = combineReducers({
  auth: AuthReducer,
  [userApi.reducerPath]: userApi.reducer,
  [productApi.reducerPath]: productApi.reducer,
  [paymentUserApi.reducerPath]: paymentUserApi.reducer,
  [baseApi.reducerPath]: baseApi.reducer,
  [cartApi.reducerPath]: cartApi.reducer,
  [shoppingApi.reducerPath]: shoppingApi.reducer,
});
export const store = configureStore({
  reducer: rootReducer,
  middleware: (getDefaultMiddleware) => [
    ...getDefaultMiddleware(),
    userApi.middleware,
    productApi.middleware,
    paymentUserApi.middleware,
    baseApi.middleware,
    cartApi.middleware,
    shoppingApi.middleware,
    AuthMiddleware,
    ErrorLogger,
  ],
});
setupListeners(store.dispatch);
export type RootState = ReturnType<typeof rootReducer>;
export type AppDispatch = typeof store.dispatch;

When I call the endpoint updateCart, the endpoint getShoppingSession should refetch. Thank you for your help.

英文:

I wanted to split the API into two parts, but the provided tag endpoint didn't refetch itself, when the invalidatesTag endpoint at the other part was called.
BaseApi:

import { createApi, fetchBaseQuery } from &quot;@reduxjs/toolkit/query/react&quot;;
export const baseApi = createApi({
baseQuery: fetchBaseQuery({ baseUrl: `${import.meta.env.VITE_SERVER}` }),
tagTypes: [&quot;Cart&quot;, &quot;Shopping&quot;, &quot;Product&quot;],
endpoints: () =&gt; ({}),
});

CartApi:

import { baseApi } from &quot;../BaseApi/baseApi&quot;;
type CartItemType = {
product_id?: string;
quantity?: number;
};
type CartType = {
_id: string;
} &amp; CartItemType;
type CartResponse = {
message: string;
data: CartType;
};
export const cartApi = baseApi.injectEndpoints({
endpoints: (builder) =&gt; ({
getCartByProDuctId: builder.query&lt;CartResponse, string&gt;({
query: (id: string) =&gt; `cart-item/${id}`,
providesTags: [&quot;Cart&quot;],
}),
createCart: builder.mutation&lt;CartResponse, CartItemType&gt;({
query: (data: CartItemType) =&gt; ({
url: &quot;/cart-item/create&quot;,
method: &quot;PUT&quot;,
body: data,
}),
}),
updateCart: builder.mutation&lt;CartResponse, CartItemType&gt;({
query: (data: CartItemType) =&gt; ({
url: &quot;/cart-item/update&quot;,
method: &quot;PATCH&quot;,
body: data,
invalidatesTags: [&quot;Shopping&quot;],
}),
}),
deleteCart: builder.mutation&lt;CartResponse, CartItemType&gt;({
query: (data: CartItemType) =&gt; ({
url: &quot;/cart-item/delete&quot;,
method: &quot;DELETE&quot;,
body: data,
}),
}),
}),
});
export const {
useGetCartByProDuctIdQuery,
useCreateCartMutation,
useUpdateCartMutation,
useDeleteCartMutation,
} = cartApi;

ShoppingApi:

import { baseApi } from &quot;../BaseApi/baseApi&quot;;
import type { ProductType } from &quot;../ProductReducer/ProductApi&quot;;
type cart_item = {
product_id: ProductType;
quantity: number;
};
type ShoppingSessionType = {
cart_items: cart_item[];
user_id?: string;
};
type shoppingType = {
id: string;
CartItemId: string;
};
export const shoppingApi = baseApi.injectEndpoints({
endpoints: (builder) =&gt; ({
getShoppingSession: builder.query&lt;ShoppingSessionType, string&gt;({
query: (id: string) =&gt; `shopping/${id}`,
providesTags: [&quot;Shopping&quot;],
}),
updateCartItem: builder.mutation&lt;ShoppingSessionType, shoppingType&gt;({
query: ({ id, CartItemId }: shoppingType) =&gt; ({
url: `shopping/update-cart-item/${id}`,
method: &quot;PATCH&quot;,
body: { CartItemId },
}),
invalidatesTags: [&quot;Shopping&quot;],
}),
updateDeleteCartItem: builder.mutation&lt;ShoppingSessionType, shoppingType&gt;({
query: ({ id, CartItemId }: shoppingType) =&gt; ({
url: `shopping/update-delete/${id}`,
method: &quot;PATCH&quot;,
body: { CartItemId },
}),
}),
}),
});
export const {
useGetShoppingSessionQuery,
useUpdateCartItemMutation,
useUpdateDeleteCartItemMutation,
} = shoppingApi;

My store setup:

import { configureStore } from &quot;@reduxjs/toolkit&quot;;
import AuthReducer from &quot;../api/AuthReducer/AuthReduce&quot;;
import { AuthMiddleware } from &quot;../middleware/AuthMiddleware&quot;;
import { combineReducers } from &quot;@reduxjs/toolkit&quot;;
import { setupListeners } from &quot;@reduxjs/toolkit/dist/query&quot;;
import { userApi } from &quot;../api/UserApi/UserApi&quot;;
import { productApi } from &quot;../api/ProductReducer/ProductApi&quot;;
import { paymentUserApi } from &quot;../api/UserApi/UserPaymentApi&quot;;
import { shoppingApi } from &quot;../api/ShoppingSessionApi/ShoppingSessionApi&quot;;
import { cartApi } from &quot;../api/CartReducer/CartApi&quot;;
import { baseApi } from &quot;../api/BaseApi/baseApi&quot;;
import { ErrorLogger } from &quot;../middleware/ErrorLogger&quot;;
const rootReducer = combineReducers({
auth: AuthReducer,
[userApi.reducerPath]: userApi.reducer,
[productApi.reducerPath]: productApi.reducer,
[paymentUserApi.reducerPath]: paymentUserApi.reducer,
[baseApi.reducerPath]: baseApi.reducer,
[cartApi.reducerPath]: cartApi.reducer,
[shoppingApi.reducerPath]: shoppingApi.reducer,
});
export const store = configureStore({
reducer: rootReducer,
middleware: (getDefaultMiddleware) =&gt; [
...getDefaultMiddleware(),
userApi.middleware,
productApi.middleware,
paymentUserApi.middleware,
baseApi.middleware,
cartApi.middleware,
shoppingApi.middleware,
AuthMiddleware,
ErrorLogger,
],
});
setupListeners(store.dispatch);
export type RootState = ReturnType&lt;typeof rootReducer&gt;;
export type AppDispatch = typeof store.dispatch;

When I call the endpoint updateCart, the endpoint getShoppingSession should refetch. Thank you for your help

答案1

得分: 0

只将您的baseApi添加到您的存储中 - 这是完全相同的API,只是每次都有更多的端点。您基本上是将相同的中间件添加了6次。

export const store = configureStore({
  reducer: {
    auth: AuthReducer,
    [baseApi.reducerPath]: userApi.reducer,
  },
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware()
    .concat(baseApi.middleware)
    .concat(AuthMiddleware)
    .concat(ErrorLogger)
});
英文:

Only add your baseApi to your store - this is all the same api, just with more endpoints every time. You are essentially adding the same middleware 6 times.

export const store = configureStore({
  reducer: {
    auth: AuthReducer,
    [baseApi.reducerPath]: userApi.reducer,
  },
  middleware: (getDefaultMiddleware) =&gt; 
    getDefaultMiddleware()
    .concat(baseApi.middleware)
    .concat(AuthMiddleware)
    .concat(ErrorLogger)
});

答案2

得分: 0

我已找到解决方案。invalidatesTag这行应该移到查询之外。

updateCart: builder.mutation<CartResponse, CartItemType>({
      query: (data: CartItemType) => ({
        url: "/cart-item/update",
        method: "PATCH",
        body: data,
        invalidatesTags: ["Shopping"],
      }),
    }),

应该改为:

updateCart: builder.mutation<CartResponse, CartItemType>({
      query: (data: CartItemType) => ({
        url: "/cart-item/update",
        method: "PATCH",
        body: data,
      }),
      invalidatesTags: ["Shopping"],
    }),
英文:

I've found my own solution for this. The line invalidatesTag should be moved out of the query.

updateCart: builder.mutation&lt;CartResponse, CartItemType&gt;({
query: (data: CartItemType) =&gt; ({
url: &quot;/cart-item/update&quot;,
method: &quot;PATCH&quot;,
body: data,
invalidatesTags: [&quot;Shopping&quot;],
}),
}),

should instead look like:

updateCart: builder.mutation&lt;CartResponse, CartItemType&gt;({
query: (data: CartItemType) =&gt; ({
url: &quot;/cart-item/update&quot;,
method: &quot;PATCH&quot;,
body: data,
}),
invalidatesTags: [&quot;Shopping&quot;],
}),

huangapple
  • 本文由 发表于 2023年7月17日 15:33:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/76702341.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定