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

如何自定义类似useFormik/useMutation的useAxiosPost Hook?

如何配置自定义useAxiosPost Hook以支持回调函数

1. 定义完整的TypeScript类型

先明确Hook的选项、响应数据和返回值的类型,确保类型安全:

// 通用API响应数据类型,支持自定义返回结构
type ApiResponse<T = unknown> = T;

// Hook的配置选项,包含成功/失败回调
interface UseAxiosPostOptions<T = unknown> {
  onSuccess?: (data: ApiResponse<T>) => void;
  onError?: (error: Error) => void;
}

// Hook的返回值,包含请求函数、加载状态和错误信息
interface UseAxiosPostReturn<T = unknown> {
  post: (url: string, data: unknown) => Promise<void>;
  loading: boolean;
  error: Error | null;
}

2. 实现Hook核心逻辑

使用useState管理加载状态与错误信息,封装axios POST请求,在请求完成后触发对应回调:

// useAxiosPost.ts
import { useState } from 'react';
import axios from 'axios';

type ApiResponse<T = unknown> = T;

interface UseAxiosPostOptions<T = unknown> {
  onSuccess?: (data: ApiResponse<T>) => void;
  onError?: (error: Error) => void;
}

interface UseAxiosPostReturn<T = unknown> {
  post: (url: string, data: unknown) => Promise<void>;
  loading: boolean;
  error: Error | null;
}

function useAxiosPost<T = unknown>({ onSuccess, onError }: UseAxiosPostOptions<T>): UseAxiosPostReturn<T> {
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<Error | null>(null);

  const post = async (url: string, data: unknown) => {
    setLoading(true);
    setError(null);
    try {
      const response = await axios.post<ApiResponse<T>>(url, data);
      // 请求成功时调用传入的onSuccess回调,传递响应数据
      onSuccess?.(response.data);
    } catch (err) {
      const requestError = err instanceof Error ? err : new Error('请求失败');
      setError(requestError);
      // 请求失败时调用传入的onError回调,传递错误对象
      onError?.(requestError);
    } finally {
      setLoading(false);
    }
  };

  return { post, loading, error };
}

export default useAxiosPost;

3. 组件中使用Hook

通过泛型指定响应数据类型,传入回调函数处理请求结果,同时可以直接使用Hook返回的状态控制UI:

import useAxiosPost from './useAxiosPost';

// 定义API返回的数据结构
interface UserResponse {
  id: number;
  name: string;
  email: string;
}

function UserForm() {
  const { post, loading, error } = useAxiosPost<UserResponse>({
    onSuccess(data) {
      // 处理成功返回的数据,比如更新状态、跳转页面
      console.log('用户创建成功:', data);
    },
    onError(error) {
      // 处理请求错误,比如展示提示
      console.error('创建用户失败:', error.message);
    },
  });

  const handleCreateUser = async () => {
    const formData = { name: '李四', email: 'lisi@example.com' };
    await post('/api/users', formData);
  };

  if (loading) return <div>提交中...</div>;
  if (error) return <div className="error">错误:{error.message}</div>;

  return (
    <button onClick={handleCreateUser} disabled={loading}>
      创建用户
    </button>
  );
}

export default UserForm;

核心设计要点

  • 泛型支持:通过<T>适配不同API的响应结构,组件使用时可获得完整的类型提示。
  • 状态封装:Hook内部维护loading和error状态,无需组件自行管理。
  • 回调触发:请求完成后自动调用传入的onSuccess/onError,与useMutation、useFormik的回调模式保持一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 04:32:31