如何将基于Context的自定义fetch封装注入react-query的查询函数中
解决方案
方案:封装自定义的useQuery/useMutation钩子(推荐)
这是最符合需求的实现方式,只需一次封装即可完全实现query/mutation函数的独立抽离,不需要在业务组件内重复处理apiFetch的获取逻辑。
步骤1:封装自定义查询钩子
import { useQuery, useMutation } from '@tanstack/react-query'; import { useApiFetch } from './你存放useApiFetch的文件路径'; // 封装通用的自定义useQuery export const useCustomQuery = (queryKey, queryFn, options = {}) => { const apiFetch = useApiFetch(); // 对原queryFn做包装,自动注入apiFetch作为第二个入参 const wrappedQueryFn = (queryContext) => queryFn(queryContext.queryKey, apiFetch); return useQuery(queryKey, wrappedQueryFn, options); }; // 同理封装mutation钩子 export const useCustomMutation = (mutationFn, options = {}) => { const apiFetch = useApiFetch(); const wrappedMutationFn = (variables) => mutationFn(variables, apiFetch); return useMutation(wrappedMutationFn, options); };
步骤2:独立维护抽离的query/mutation函数
完全按照期望的写法编写业务查询逻辑,不需要依赖任何组件内的状态:
// 可以统一放在单独的api/queries.js文件中维护 // 查询函数第一个参数为queryKey,第二个为自动注入的apiFetch export const getTodoListQuery = (key, apiFetch) => { return apiFetch('/api/todos', { method: 'GET' }); }; export const createTodoMutation = (todoData, apiFetch) => { return apiFetch('/api/todos', { method: 'POST', body: JSON.stringify(todoData) }); };
步骤3:组件内直接调用
不需要在组件内手动获取apiFetch,也不需要写内联函数:
import { useCustomQuery, useCustomMutation } from './你封装钩子的路径'; import { getTodoListQuery, createTodoMutation } from './api/queries'; function TodoComponent() { // 直接调用,写法和预期的完全一致 const { data: todoList } = useCustomQuery('todos', getTodoListQuery); const { mutate: createTodo } = useCustomMutation(createTodoMutation); return <div>...</div>; }
方案优势
- 完全满足业务查询逻辑和组件视图分离的需求,所有接口请求逻辑可以统一维护
- 避免了每个组件都要重复调用
useApiFetch、编写内联查询函数的冗余代码 - 后续如果需要新增通用的查询配置(比如统一重试策略、超时时间、错误兜底逻辑),只需要修改自定义钩子即可,无需改动业务代码
内容的提问来源于stack exchange,提问作者rbhalla
相关产品推荐
相关产品推荐

