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

如何将基于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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 14:09:02