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

如何在React函数中调用自定义useAxios Hook处理点击触发请求?

解决React中点击事件函数调用自定义Hook的问题

需求是在点击触发的handleNewSale函数中调用自定义Hook useAxios,但React不允许在普通函数内调用Hook,需要调整实现方式。

原自定义Hook代码

import { useState, useEffect } from "react";
import Axios from "axios";

const useAxios = (method: string, param: string, data: any) => {
  const [response, setResponse] = useState([]);
  const [error, setError] = useState([]);

  const fetchData = () => {
    Axios({
      method: method,
      url: `https://gernagroup-server.herokuapp.com/${param}`,
      data: data,
    })
      .then((response) => {
        setResponse(response.data);
      })
      .catch((err) => {
        setError(err);
      });
  };

  useEffect(() => {
    fetchData();
  }, []);

  return { response, error };
};

export default useAxios;

原点击事件函数及触发按钮

const handleNewSale = () => {
  Axios.post("https://gernagroup-server.herokuapp.com/new-sale", {
    data: selectedValues,
  })
    .then((response) => {
      console.log(response);
      showModal(ResultType.success, "New sale added successfully!");
    })
    .catch((err) => {
      console.log(err);
      showModal(ResultType.error, "Something went wrong");
    });
};
<Button text="New sale" onClick={handleNewSale} />

解决方法

1. 改造useAxios Hook,支持手动触发请求

原Hook会在组件挂载时自动执行请求,不符合点击触发的需求。我们移除自动执行逻辑,将请求函数暴露出来,让外部可以手动调用:

import { useState } from "react";
import Axios from "axios";

const useAxios = () => {
  const [response, setResponse] = useState<any>(null);
  const [error, setError] = useState<any>(null);
  const [isLoading, setIsLoading] = useState(false); // 可选:添加加载状态优化体验

  const fetchData = async (method: string, param: string, data: any) => {
    setIsLoading(true);
    try {
      const res = await Axios({
        method: method,
        url: `https://gernagroup-server.herokuapp.com/${param}`,
        data: data,
      });
      setResponse(res.data);
      setError(null);
    } catch (err) {
      setError(err);
      setResponse(null);
    } finally {
      setIsLoading(false);
    }
  };

  return { response, error, isLoading, fetchData };
};

export default useAxios;

2. 在组件中使用改造后的Hook

在组件顶层调用useAxios,拿到fetchData函数和状态,然后在handleNewSale中触发请求,通过监听状态变化处理弹窗逻辑:

import useAxios from "./path/to/useAxios";

// 组件内部
const { response, error, isLoading, fetchData } = useAxios();

// 监听响应和错误,处理弹窗
useEffect(() => {
  if (response) {
    console.log(response);
    showModal(ResultType.success, "New sale added successfully!");
  }
  if (error) {
    console.log(error);
    showModal(ResultType.error, "Something went wrong");
  }
}, [response, error]);

const handleNewSale = () => {
  // 调用fetchData发起请求
  fetchData("post", "new-sale", { data: selectedValues });
};

关键说明

  • React Hook必须在组件顶层或其他Hook中调用,因此我们将useAxios放在组件顶层,拿到可手动触发的fetchData函数后,再在点击事件中调用这个函数。
  • isLoading状态可用于优化交互,比如点击按钮后禁用按钮直到请求完成。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 04:48:29