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

使用Next.js+RTK Query配置queryFn报错,求解决方法

修复Next.js中RTK Query使用queryFn时的报错问题

在Next.js项目中使用RTK Query创建API,采用queryFn而非query配置端点时出现报错,核心问题是RTK Query对queryFn的返回格式有严格要求,而当前代码中ContentApiClient.getNewMovies返回的是Axios原生响应结构,不符合RTK Query的规范。

问题代码

ContentStore.ts

export const contentApi = createApi({
    reducerPath: 'api/content',
    baseQuery: fetchBaseQuery({
        baseUrl: ''
    }),
    endpoints: (build) => ({
        getNewMovies: build.query<any, ContentApi.GetNewMoviesRequestParams>({
            queryFn: (params: ContentApi.GetNewMoviesRequestParams) => ContentApiClient.getNewMovies(params),
        })
    })
})

ContentApiClient.ts

class ContentApiClientClass extends ApiClientClass {
    baseUrl = ContentApiClientConstants.baseUrl

    async getNewMovies(params?: ContentApi.GetNewMoviesRequestParams) {
        return await this.getRequest({
            url: 'https://jsonplaceholder.typicode.com/posts',
            params
        })
    }
}

export const ContentApiClient = new ContentApiClientClass()

ApiClient.class.ts

class ApiClientClass {
    axiosInstance: AxiosInstance

    constructor(config?: AxiosRequestConfig) {
        this.axiosInstance = this.createInstance(config)
    }

    private createInstance(config?: AxiosRequestConfig) {
        return axios.create({
            ...config,
            timeout: 60000,
            headers: {
                'Cache-control': 'no-cache',
                ...(config?.headers || {})
            }
        })
    }

    private async axiosRequest<R>(context: AxiosRequestConfig): Promise<AxiosResponse<R>> {
        try {
            return await this.axiosInstance(context)
        } catch (error) {
            if (axios.isCancel(error)) {
                throw new Error(`Request has aborted. Url: ${context.url}`)
            }

            throw error
        }
    }

    async getRequest<R>(context: AxiosRequestConfig): Promise<AxiosResponse<R>> {
        return await this.axiosRequest({
            ...context,
            method: 'get'
        })
    }
}

export default ApiClientClass

修复方案

RTK Query要求queryFn必须返回一个包含以下结构的对象:

  • 成功时:{ data: T },其中T是响应数据类型
  • 失败时:{ error: { status?: number, data?: any } },需包含错误状态码和错误数据

修改ContentStore.ts中的queryFn,将Axios响应转换为RTK Query要求的格式:

import { AxiosError } from 'axios';

export const contentApi = createApi({
    reducerPath: 'api/content',
    // 使用queryFn时baseQuery可保留或设为identity(不影响核心逻辑)
    baseQuery: fetchBaseQuery({ baseUrl: '' }),
    endpoints: (build) => ({
        getNewMovies: build.query<any, ContentApi.GetNewMoviesRequestParams>({
            queryFn: async (params) => {
                try {
                    const response = await ContentApiClient.getNewMovies(params);
                    // 提取Axios响应体,转为RTK Query成功格式
                    return { data: response.data };
                } catch (error) {
                    const axiosError = error as AxiosError;
                    // 提取错误信息,转为RTK Query错误格式
                    return {
                        error: {
                            status: axiosError.response?.status,
                            data: axiosError.response?.data || axiosError.message
                        }
                    };
                }
            },
        })
    })
})

额外说明

  1. 如果不需要baseQuery,可以将其替换为baseQuery: () => ({})或从@reduxjs/toolkit/query导入identity,因为queryFn会完全接管请求逻辑。
  2. 建议给响应和错误定义明确的TypeScript类型,替代any,提升代码类型安全性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 11:09:14