如何在RTK Query baseQuery中实现请求体与参数驼峰转蛇形
RTK Query 请求参数/请求体蛇形命名转换实现方案
你的判断是对的,请求侧的键名转换统一放在自定义baseQuery层实现是最优解,不需要在每个endpoint单独写重复逻辑,维护成本最低。
实现核心逻辑:
- 调用原始baseQuery发起请求前,拦截传入的请求参数,把普通对象类型的
body(请求体)和params(URL查询参数)的键名从驼峰转为下划线 - 请求返回后保留你原有的响应数据驼峰转换逻辑即可
注意要跳过FormData、Blob、文件流这类特殊格式的请求体,避免破坏上传类接口的正常逻辑。
完整实现代码
假设你用的是RTK Query官方提供的fetchBaseQuery,完整代码如下:
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react' // 键名转换工具,可引入第三方库如humps,也可以自己实现 import { camelizeKeys, snakifyKeys } from './utils/keyTransform' // 初始化原始baseQuery实例 const rawBaseQuery = fetchBaseQuery({ baseUrl: '/your-api-prefix' }) const api = createApi({ reducerPath: 'API', baseQuery: async (args, api, extraOptions) => { let finalArgs = args // 仅当args是请求配置对象(而非纯字符串URL)时处理参数 if (typeof args === 'object' && !extraOptions?.skipKeyTransform) { finalArgs = { ...args } // 处理请求体:跳过FormData、Blob等特殊格式 if ( finalArgs.body && typeof finalArgs.body === 'object' && !(finalArgs.body instanceof FormData) && !(finalArgs.body instanceof Blob) && !(finalArgs.body instanceof ArrayBuffer) ) { finalArgs.body = snakifyKeys(finalArgs.body) } // 处理URL查询参数 if (finalArgs.params && typeof finalArgs.params === 'object') { finalArgs.params = snakifyKeys(finalArgs.params) } } // 发起请求 const result = await rawBaseQuery(finalArgs, api, extraOptions) const { data, meta, error } = result // 保留原有响应转驼峰逻辑 return { ...result, data: data ? camelizeKeys(data) : data } }, endpoints: () => ({}), })
附:原生JS实现键名转换工具
如果不想引入第三方依赖,可以直接用下面的递归转换函数,覆盖绝大多数普通对象、数组嵌套场景:
// 驼峰字符串转下划线 const toSnake = (str) => str.replace(/[A-Z]/g, (match) => `_${match.toLowerCase()}`) // 下划线字符串转驼峰 const toCamel = (str) => str.replace(/_([a-z])/g, (_, char) => char.toUpperCase()) // 递归遍历对象转换键名 const keyTransform = (target, transformFn) => { if (Array.isArray(target)) return target.map(item => keyTransform(item, transformFn)) if (target && typeof target === 'object' && target.constructor === Object) { return Object.keys(target).reduce((acc, key) => { acc[transformFn(key)] = keyTransform(target[key], transformFn) return acc }, {}) } return target } const snakifyKeys = (data) => keyTransform(data, toSnake) const camelizeKeys = (data) => keyTransform(data, toCamel)
扩展说明
- 如果你用的是axios-base-query或者其他自定义baseQuery,逻辑完全通用,只需要在调用原始baseQuery前修改传入的请求配置即可
- 代码里预留了
skipKeyTransform标记,如果有个别接口不需要做键名转换,调用时传入extraOptions: { skipKeyTransform: true }即可跳过转换 - 如果需要处理请求头里的特殊字段,也可以用同样的思路在请求前修改
finalArgs.headers配置
内容的提问来源于stack exchange,提问作者programmer
相关产品推荐
相关产品推荐

