簡體   English   中英

如何使用自定義 React 鈎子通過 Axios 發出 POST 或 DELETE 請求

[英]How to use a custom React hook to make a POST or DELETE request with Axios

我正在嘗試在 React 中創建一個通用的 useAxios 鈎子。 我希望能夠將此鈎子導入其他組件以發出獲取、發布和刪除請求。 我已經創建了鈎子,它可以很好地發出 Get 請求,但我一直堅持如何使它適用於 Post/Delete 請求。

問題是當用戶單擊保存或刪除按鈕時我會發出發布/刪除請求,但我無法從事件處理程序 function 或 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 鈎子,但我最終會在整個應用程序中重復代碼。

假設您的DELETE路由與GET路由相同,您只需將方法類型存儲在本地 state 變量中並更改它:

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 ) 緊密耦合在一起。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM