英文:
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 "@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
答案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) =>
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<CartResponse, CartItemType>({
query: (data: CartItemType) => ({
url: "/cart-item/update",
method: "PATCH",
body: data,
invalidatesTags: ["Shopping"],
}),
}),
should instead look like:
updateCart: builder.mutation<CartResponse, CartItemType>({
query: (data: CartItemType) => ({
url: "/cart-item/update",
method: "PATCH",
body: data,
}),
invalidatesTags: ["Shopping"],
}),
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论