You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RTK Query useGetAllFavQuery报错:不是函数问题求助

Redux Toolkit Query收藏API调用报错:useGetAllFavQuery不是函数

我基于Redux Toolkit Query开发了一套处理用户收藏列表的API,包含获取收藏、添加收藏、删除收藏功能,但调用获取收藏列表的请求时,报错TypeError: (0 , api_favApi__WEBPACK_IMPORTED_MODULE_1_.useGetAllFavQuery) is not a function,并且console.log(useGetAllFavQuery)结果为undefined。


相关代码

收藏API代码(favApi.js)

import { createApi, fakeBaseQuery } from "@reduxjs/toolkit/query";
import {
  arrayRemove,
  arrayUnion,
  doc,
  getDoc,
  updateDoc,
} from "firebase/firestore";
import { userConverter } from "../converter/userConverter";
import { firestore } from "../firebase";

export const favApi = createApi({
  baseQuery: fakeBaseQuery(),
  reducerPath: "favApi",
  tagTypes: ["Favourite"],
  refetchOnMountOrArgChange: true,
  endpoints: (builder) => ({
    getAllFav: builder.query({
      async queryFn(email) {
        try {
          if (!email) {
            return { data: [] };
          }
          const userLink = doc(firestore, "users", email).withConverter(
            userConverter
          );
          const user = await getDoc(userLink);

          const userData = user.data();
          if (userData) {
            return { data: userData.favourite };
          }
          return { data: [] };
        } catch (err) {
          return { error: err };
        }
      },
      invalidatesTags: ["Favourite"],
    }),
    addToFav: builder.mutation({
      async queryFn(email, item) {
        try {
          if (!email) {
            return { data: [] };
          }
          const userLink = doc(firestore, "users", email).withConverter(
            userConverter
          );

          await updateDoc(userLink, {
            favourite: arrayUnion(item),
          });
          return { data: item };
        } catch (err) {
          return { error: err };
        }
      },
      invalidatesTags: ["Favourite"],
    }),
    removeFromeFav: builder.mutation({
      async queryFn(email, item) {
        try {
          if (!email) {
            return { data: [] };
          }
          const userLink = doc(firestore, "users", email).withConverter(
            userConverter
          );

          await updateDoc(userLink, {
            favourite: arrayRemove(item),
          });
          return { data: item };
        } catch (err) {
          return { error: err };
        }
      },
      invalidatesTags: ["Favourite"],
    }),
  }),
});

export const {
  useGetAllFavQuery,
  useAddToFavMutation,
  useRemoveFromeFavMutation,
} = favApi;

自定义useFav Hook代码

import {
  useAddToFavMutation,
  useGetAllFavQuery,
  useRemoveFromFavMutation,
} from "../api/favApi";
import { useAuth } from "./useAuth";

export const useFav = () => {
  const { user } = useAuth();
  const { data: favourites = [] } = useGetAllFavQuery(user?.email);

  const [addFav, addRes] = useAddToFavMutation();
  const [removeFav, removeRes] = useRemoveFromFavMutation();

  const isItemFav = (id) => favourites.some((item) => item.id === id);

  const addToFav = async (data) => {
    await addFav({ email: user?.email, item: data });
  };

  const removeFromFav = async (data) => {
    await removeFav({ email: user?.email, item: data });
  };

  return {
    isFav: isItemFav,
    isDisabled: addRes.isLoading || removeRes.isLoading,
    addToFav,
    removeFromFav,
  };
};

Store配置代码

import { combineReducers, configureStore } from "@reduxjs/toolkit";
import { booksApi } from "../api/booksApi";
import { favApi } from "../api/favApi";
import { listenerMiddleware } from "./middlewares/userMiddleware";
import userReducer from "./reducers/userSlice";

const rootReducer = combineReducers({
  [booksApi.reducerPath]: booksApi.reducer,
  [favApi.reducerPath]: favApi.reducer,
  userReducer,
});

export const store = configureStore({
  reducer: rootReducer,
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware({ serializableCheck: false }).concat(
      booksApi.middleware,
      favApi.middleware,
      listenerMiddleware.middleware
    ),
});

错误详情

报错发生在useFav Hook的这一行:

const { data: favourites = [] } = useGetAllFavQuery(user?.email);

具体错误信息:

api_favApi__WEBPACK_IMPORTED_MODULE_1_.useGetAllFavQuery) is not a function
TypeError: (0 , api_favApi__WEBPACK_IMPORTED_MODULE_1_.useGetAllFavQuery) is not a function

问题排查与解决方案

1. 修复拼写错误

API中删除收藏的端点命名为removeFromeFav(多了一个e),导出的Hook是useRemoveFromeFavMutation,但自定义Hook中导入的是useRemoveFromFavMutation(正确拼写),这会导致导入失败,甚至干扰模块整体导出解析。

修复:
修改favApi.js中的端点名和导出语句:

// 修改端点命名
removeFromFav: builder.mutation({
  // ... 原有逻辑
}),

// 修改导出语句
export const {
  useGetAllFavQuery,
  useAddToFavMutation,
  useRemoveFromFavMutation,
} = favApi;

2. 修正queryFn参数格式

RTK Query的queryFn仅接受单个参数,但你的addToFav和removeFromeFav的queryFn写了两个参数email, item,这会导致参数解析错误,进而影响Hook生成。

修复:
将queryFn改为接收单个对象参数,调用时传入包含email和item的对象:

// 以addToFav为例修改queryFn
addToFav: builder.mutation({
  async queryFn({ email, item }) {
    try {
      if (!email) {
        return { data: [] };
      }
      const userLink = doc(firestore, "users", email).withConverter(
        userConverter
      );

      await updateDoc(userLink, {
        favourite: arrayUnion(item),
      });
      return { data: item };
    } catch (err) {
      return { error: err };
    }
  },
  invalidatesTags: ["Favourite"],
}),

3. 验证导入路径

确认自定义Hook中../api/favApi的路径是否正确,注意文件名大小写是否匹配(比如文件名为FavApi.js但导入写favApi),以及文件是否存在于指定目录。

4. 更新RTK版本

旧版本的@reduxjs/toolkit可能存在Hook生成的bug,执行以下命令更新到最新版本:

npm install @reduxjs/toolkit@latest

5. 清理缓存重启服务

Webpack缓存可能导致模块导出异常,尝试清理缓存后重启开发服务器:

  • Create React App:npm start --reset-cache
  • Vite:删除node_modules/.vite目录后重启

内容的提问来源于stack exchange,提问作者palew

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 21:47:06