如何使用自定义 React 钩子通过 Axios 发出 POST 或 DELETE 请求
Posted
技术标签:
【中文标题】如何使用自定义 React 钩子通过 Axios 发出 POST 或 DELETE 请求【英文标题】:How to use a custom React hook to make a POST or DELETE request with Axios 【发布时间】:2022-01-22 08:50:19 【问题描述】:我正在尝试在 React 中创建一个通用的 useAxios 钩子。我希望能够将此钩子导入其他组件以发出 Get、Post 和 Delete 请求。我已经创建了钩子,它可以很好地发出 Get 请求,但我一直在思考如何使它适用于 Post/Delete 请求。
问题是当用户单击保存或删除按钮时我会发出 Post/Delete 请求,但我无法从事件处理函数或 useEffect 调用 React 挂钩。
下面是我创建的通用钩子:
import useState, useEffect from "react";
import axios from "axios";
export interface AxiosConfig<D>
method?: 'get' | 'post' | 'delete' | 'put';
url: string;
data?: D;
params?: URLSearchParams;
export const useAxios = <T, D = undefined >(config: AxiosConfig<D>) =>
const [responseData, setResponseData] = useState<T>();
const [isLoading, setIsloading] = useState(true);
const [isError, setIsError] = useState(false);
useEffect(() =>
const controller = new AbortController();
const axiosRequest = async () =>
try
const response = await axios( ...config, signal: controller.signal )
setResponseData(response.data)
setIsloading(false);
catch (error)
setIsError(true);
setIsloading(false);
axiosRequest();
return () =>
controller.abort();
, [config.url, config.method, config.data, config.params])
return responseData, isLoading, isError
这是我想发出删除请求的组件示例
import useParams from 'react-router';
import useAxios from '../../api/hooks/useAxios';
export interface IItem
title: string;
info: string;
export default function Item()
const id = useParams<id?: string>();
const responseData: item, isLoading, isError = useAxios<IItem>(
method: 'get',
url: `http://localhost:3000/items/$id`
)
const handleDelete = () =>
//not sure what to do here. Need to make DELETE request
return (
<div>
isLoading && <p className='loading'>Loading...</p>
isError && <p className='error'>Could Not Load Item</p>
item && (
<>
<h2>item.title</h2>
<p>item.info</p>
<button onClick=handleDelete>Delete</button>
</>
)
</div>
)
我可以直接在 Item 组件中发出 axios 请求,而不使用我的 useAxios 挂钩,但我最终会在整个应用程序中重复代码。
【问题讨论】:
您正在尝试减少冗余,但我不建议您在整个组件中插入 API 请求,因为这会导致冗余较少但 API 紧张的组件。您最好使用推荐的方法在商店级别处理您的请求,并且可能有一个通用的操作创建器。 【参考方案1】:假设您的 DELETE
路由与 GET
路由相同,您只需将方法类型存储在本地状态变量中并进行更改:
const id = useParams<id?: string>();
const [method, setMethod] = useState('get');
const responseData: item, isLoading, isError = useAxios<IItem>(
method,
url: `http://localhost:3000/items/$id`
);
const handleDelete = () => setMethod('delete');
但是,我想您会意识到这只能解决部分问题,即您将组件的返回 JSX 与 GET
请求 (IItem
) 的响应类型紧密耦合。
【讨论】:
谢谢您,这确实可以删除该项目!将组件的 JSX 耦合到 API 响应是否被认为是不好的做法?将 API 调用 eslewhere 并将结果作为 props 传递给组件会更好吗? 如果组件在没有获取数据的情况下无法真正发挥作用,那么向上获取并作为 props 传递更为惯用。以上是关于如何使用自定义 React 钩子通过 Axios 发出 POST 或 DELETE 请求的主要内容,如果未能解决你的问题,请参考以下文章
在 React 中,如何在所有组件中拥有一个自定义钩子实例?
如何测试使用自定义 TypeScript React Hook 的组件?
如何测试使用自定义TypeScript React Hook的组件?