调用RTK Query懒加载钩子报错:fetchInvoicesByOffice不是函数
解决RTK Query懒加载钩子报错“fetchInvoicesByOffice is not a function”
以下是几个常见的问题排查点和解决方案:
1. 检查懒加载钩子的解构顺序
RTK Query的懒加载钩子返回的是一个数组,第一个元素才是触发请求的函数,第二个是包含状态(data、isLoading等)的对象。如果解构顺序错误,就会出现“不是函数”的报错。
错误写法:
// 错误:把状态对象当成了请求函数 const { fetchInvoicesByOffice, data } = useLazyFetchInvoicesByOfficeQuery();
正确写法:
// 正确:数组解构,第一个元素是请求触发函数 const [fetchInvoicesByOffice, { data: invoices, isLoading, error }] = useLazyFetchInvoicesByOfficeQuery();
2. 排查API切片中的重复端点
你提到代码中存在重复的fetchInvoice端点,RTK Query不允许同名端点——后续定义的同名端点会覆盖之前的,导致自动生成的钩子出现异常。
错误示例(重复端点名称):
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'; export const apiSlice = createApi({ reducerPath: 'api', baseQuery: fetchBaseQuery({ baseUrl: '/api' }), endpoints: (builder) => ({ // 第一个端点 fetchInvoices: builder.query({ query: () => '/invoices' }), // 重复命名的端点,会覆盖上面的定义 fetchInvoices: builder.query({ query: (officeId) => `/invoices/office/${officeId}` }) }) });
正确做法:给每个端点设置唯一的名称,比如区分按办公室查询和全局查询:
export const apiSlice = createApi({ reducerPath: 'api', baseQuery: fetchBaseQuery({ baseUrl: '/api' }), endpoints: (builder) => ({ fetchInvoices: builder.query({ query: () => '/invoices' }), // 唯一命名的端点,对应useLazyFetchInvoicesByOfficeQuery钩子 fetchInvoicesByOffice: builder.query({ query: (officeId) => `/invoices/office/${officeId}` }) }) }); // 导出自动生成的钩子 export const { useLazyFetchInvoicesByOfficeQuery } = apiSlice;
3. 确认Store配置正确注册API切片
如果Store没有正确注册RTK Query的API切片,钩子无法正常工作。确保配置中包含了API切片的reducer和middleware:
import { configureStore } from '@reduxjs/toolkit'; import { apiSlice } from './features/invoices/invoiceSlice'; export const store = configureStore({ reducer: { // 必须注册API切片的reducer [apiSlice.reducerPath]: apiSlice.reducer, }, // 必须添加API切片的middleware middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(apiSlice.middleware), });
4. 确保正确导入懒加载钩子
注意区分普通查询钩子(useFetchInvoicesByOfficeQuery)和懒加载钩子(useLazyFetchInvoicesByOfficeQuery),必须导入带useLazy前缀的版本:
// 正确导入懒加载钩子 import { useLazyFetchInvoicesByOfficeQuery } from '../features/invoices/invoiceSlice';
正确使用示例
以下是在useEffect和点击事件中使用懒加载钩子的正确代码:
import { useState, useEffect } from 'react'; import { useLazyFetchInvoicesByOfficeQuery } from '../features/invoices/invoiceSlice'; const InvoiceList = () => { const [selectedOfficeId, setSelectedOfficeId] = useState(''); const [fetchInvoicesByOffice, { data: invoices, isLoading, error }] = useLazyFetchInvoicesByOfficeQuery(); // 在useEffect中触发请求 useEffect(() => { if (selectedOfficeId) { fetchInvoicesByOffice(selectedOfficeId); } }, [selectedOfficeId, fetchInvoicesByOffice]); // 在点击事件中触发请求 const handleOfficeClick = (officeId) => { setSelectedOfficeId(officeId); fetchInvoicesByOffice(officeId); }; return ( <div> <button onClick={() => handleOfficeClick('office-001')}>加载办公室001的发票</button> {isLoading && <p>加载中...</p>} {error && <p>加载失败:{error.message}</p>} {invoices && ( <ul> {invoices.map(invoice => ( <li key={invoice.id}>{invoice.number} - {invoice.amount}</li> ))} </ul> )} </div> ); }; export default InvoiceList;
内容的提问来源于stack exchange,提问作者cruz
相关产品推荐
相关产品推荐

