#javascript #reactjs #typescript #axios
Вопрос:
Это мой первый вопрос, поэтому дайте мне знать, как я могу улучшить.
У меня есть следующая функция извлечения axios:
export enum RequestMethod {
GET = 'GET',
POST = 'POST',
PUT = 'PUT',
PATCH = 'PATCH',
DELETE = 'DELETE',
}
export const fetchAxiosAPI = async (
url: string,
method: RequestMethod,
data = {},
options = {}
) => {
let resu<
try {
result = await axios({
method,
url: `${process.env.REACT_APP_API_URL}/${url}`,
data,
...options,
validateStatus: () => {
return true;
},
}).then(response => response.data);
} catch (err) {
return null;
}
const errorStatus = result.error.status;
if (errorStatus === 401) {
localStorage.removeItem('access_token');
history.push('/login');
}
if (errorStatus === 404) {
history.replace(NOT_FOUND);
}
if (errorStatus === 500) {
history.replace(INTERNAL_SERVER_ERROR);
}
return resu<
};
Это выглядит некрасиво, использует ожидание, а затем (что мы не должны использовать).
У меня есть два вопроса:
- Как я могу передать универсальный тип текста в эту функцию в качестве параметра, который будет выводить типизацию текста для ответа на вызов API (Обещание)? Я нашел и пример использования axios[имя метода], например:
axios.get<Пользователь[]>(url)
Но я не нашел способа передать универсальный метод с использованием общего метода axios, как показано в моем примере кода.
- Как обрабатывать статусы ошибок, перехватывать блок и ждать/затем использовать 1 из них? В принципе, как переписать
fetchAxiosAPI
функцию.
Ответ №1:
Если я правильно читаю документацию и index.d.ts
файл, axios.request
я должен это сделать. Из документов:
Для удобства для всех поддерживаемых методов запроса были предоставлены псевдонимы.
axios.request(config)
…
и в index.d.ts
:
export interface AxiosInstance { (config: AxiosRequestConfig): AxiosPromise; (url: string, config?: AxiosRequestConfig): AxiosPromise; defaults: AxiosRequestConfig; interceptors: { request: AxiosInterceptorManager<AxiosRequestConfig>; response: AxiosInterceptorManager<AxiosResponse>; }; getUri(config?: AxiosRequestConfig): string; request<T = any, R = AxiosResponse<T>> (config: AxiosRequestConfig): Promise<R>; get<T = any, R = AxiosResponse<T>>(url: string, config?: AxiosRequestConfig): Promise<R>; delete<T = any, R = AxiosResponse<T>>(url: string, config?: AxiosRequestConfig): Promise<R>; head<T = any, R = AxiosResponse<T>>(url: string, config?: AxiosRequestConfig): Promise<R>; options<T = any, R = AxiosResponse<T>>(url: string, config?: AxiosRequestConfig): Promise<R>; post<T = any, R = AxiosResponse<T>>(url: string, data?: any, config?: AxiosRequestConfig): Promise<R>; put<T = any, R = AxiosResponse<T>>(url: string, data?: any, config?: AxiosRequestConfig): Promise<R>; patch<T = any, R = AxiosResponse<T>>(url: string, data?: any, config?: AxiosRequestConfig): Promise<R>; } export interface AxiosStatic extends AxiosInstance { create(config?: AxiosRequestConfig): AxiosInstance; Cancel: CancelStatic; CancelToken: CancelTokenStatic; isCancel(value: any): boolean; all<T>(values: (T | Promise<T>)[]): Promise<T[]>; spread<T, R>(callback: (...args: T[]) => R): (array: T[]) => R; isAxiosError(payload: any): payload is AxiosError; } declare const axios: AxiosStatic;
Обратите внимание, что request
он просто принимает объект конфигурации, как axios
и сама функция , но в отличие axios
от него имеет параметры универсального типа, которые вы видели, используемые в get
, post
, и тому подобное.
Так что что-то вроде этого смотрите ***
в комментариях:
export const fetchAxiosAPI = async <T>(
// ^^^−−−−−−−−−−− *** type parameter
url: string,
method: RequestMethod,
data = {},
options = {}
) => {
let result: T;
try {
// *** Get the response using `axios.request` with the type argument
const response = await axios.request<T>({
method,
url: `${process.env.REACT_APP_API_URL}/${url}`,
data,
...options,
validateStatus: () => {
return true;
},
});
// *** Get the result
result = response.data;
} catch (err) {
return null; // *** This is poor practice; allow the error to propagate
// or throw a new error
}
const errorStatus = result.error.status;
if (errorStatus === 401) {
localStorage.removeItem('access_token');
history.push('/login');
}
if (errorStatus === 404) {
history.replace(NOT_FOUND);
}
if (errorStatus === 500) {
history.replace(INTERNAL_SERVER_ERROR);
}
return resu<
};
Комментарии:
1. Спасибо, оказывается, мне нужно использовать axios.request. Хорошая ли практика заключать мою функцию в блок tr/catch?
2. @MindaugasN — Вызов функции, да, или вызов функции, которая ее вызывает, или той, которая ее вызывает, и т. Д. Вы не хотите скрывать тот факт, что произошла ошибка, от этих других функций или заставлять их всех проверять возвращаемые значения. Вместо этого используйте один обработчик ошибок на максимально возможном уровне (обычно обработчик событий или аналогичный, который запустил цепочку вызовов).