如何无需函数参数与柯里化,向React Query mutation函数传入Axios?
解决方案:用闭包绑定Axios实例,避免柯里化
你不需要用原型来解决这个问题——原型方案会因为共享实例导致状态冲突(多个useMutationFactory调用会覆盖原型上的Axios实例)。更简单可靠的方式是利用闭包,在useMutationFactory内部生成绑定了当前Axios实例的工具方法,直接传递给用户的mutation函数。
具体实现步骤
1. 改造useMutationFactory,生成绑定Axios的工具对象
在工厂函数内部,基于当前创建的Axios实例封装好需要的HTTP方法,再把这个工具对象作为参数传给用户的mutation函数:
import { useMutation } from '@tanstack/react-query'; import { Axios } from 'axios'; // 定义工具方法类型,和Axios原生方法类型保持一致 type MutationTools = { queryGet: Axios['get']; queryPost: Axios['post']; queryPut: Axios['put']; queryDelete: Axios['delete']; // 按需添加其他HTTP方法 }; function useMutationFactory( mutationFunction: (tools: MutationTools) => (params: any) => Promise<any> ) { const baseURL = getBaseURL(); const axios = useAxios({ baseURL }); // 创建绑定当前Axios实例的工具方法 const mutationTools: MutationTools = { queryGet: (...params) => axios.get(...params), queryPost: (...params) => axios.post(...params), queryPut: (...params) => axios.put(...params), queryDelete: (...params) => axios.delete(...params), }; // 将工具对象传入用户的mutation函数,再传递给useMutation return useMutation((params) => mutationFunction(mutationTools)(params)); }
2. 用户侧使用方式
用户编写mutation函数时,直接从参数中解构需要的工具方法即可,完全不用接触Axios实例:
const { mutate } = useMutationFactory(({ queryGet }) => async (params) => { // 直接用工具方法发起请求 const response = await queryGet('/api/data', { params }); return response.data; }); // 调用mutation mutate({ id: 123 });
方案优势
- 每个
useMutationFactory调用都会创建独立的Axios实例和对应工具方法,闭包保留当前实例引用,不会出现跨实例状态污染。 - 用户无需手动处理Axios注入,也不用写柯里化嵌套函数,代码简洁直观。
- 工具方法类型和Axios原生方法完全一致,能保留完整的类型提示,提升开发体验。
替代方案:React Context(适合跨组件共享场景)
如果需要在多个组件或mutation中共享同一个Axios实例,可以用React Context注入:
- 创建Context:
import { createContext, useContext } from 'react'; import { Axios } from 'axios'; const AxiosContext = createContext<Axios | null>(null);
- 在工厂函数中提供Context并封装工具:
function useMutationFactory(mutationFunction: (params: any) => Promise<any>) { const baseURL = getBaseURL(); const axios = useAxios({ baseURL }); // 封装绑定当前Axios的工具方法 const mutationTools = { queryGet: (...args) => axios.get(...args), }; return useMutation((params) => mutationFunction(params, mutationTools)); }
不过这个方案相对复杂,若只是需要每个mutation工厂实例对应独立Axios,闭包方案已经足够。
内容的提问来源于stack exchange,提问作者Anthony Ma
相关产品推荐
相关产品推荐

