如果第一个api失败,防止进一步调用自定义useAxios钩子



我有一个Dashboard组件,它通过三个API调用来获取小部件数据。

如果任何API调用失败,则刷新令牌。

但是,当Dashboard呈现时,它单独调用API,它们不会等待检查第一个API调用是否失败或令牌是否刷新。每个api调用都以另一个调用来刷新令牌结束。

它应该在第一个API调用失败时停止并刷新令牌。

但是它对每个请求都这样做。我怎样才能防止这种行为呢?

看来我需要按顺序提出请求。

const Dashboard = () => {
const { response: studentResponse } = useAxios(ApiConfig.STUDENT.GET_STUDENTS);
const { response: courseResponse } = useAxios(ApiConfig.COURSE.GET_COURSES);
const { response: feesResponse } = useAxios(ApiConfig.FEES.GET_TOTAL);
return (
<Box padding={2} width="100%">
<Stack direction={'row'} justifyContent="space-between" gap={2} mb={10}>
<NewWidget type={'student'} counter={studentResponse?.data?.length} />
<NewWidget type={'course'} counter={courseResponse?.data?.length} />
<NewWidget type={'earning'} counter={feesResponse?.data} />
</Stack>
</Box>
);
};
export default Dashboard;

use-axios.js

import { useState, useEffect } from 'react';
import axios from 'axios';
import history from '../utils/history';
import refreshToken from './refresh-token';
const Client = axios.create();
Client.defaults.baseURL = 'http://localhost:3000/api/v1';
const getUser = () => {
const user = localStorage.getItem('user');
return user ? JSON.parse(user) : null;
};
const updateLocalStorageAccessToken = (accessToken) => {
const user = getUser();
user.accessToken = accessToken;
localStorage.setItem('user', JSON.stringify(user));
};
Client.interceptors.request.use(
(config) => {
const user = getUser();
config.headers.Authorization = user?.accessToken;
return config;
},
(error) =>
// Do something with request error
Promise.reject(error)
);
Client.interceptors.response.use(
(response) => response,
(error) => {
// Reject promise if usual error
if (error.response.status !== 401) {
return Promise.reject(error);
}
const user = getUser();
const status = error.response ? error.response.status : null;
const originalRequest = error.config;
console.log(originalRequest);
if (status === 401 && originalRequest.url !== '/auth/refresh-token') {
refreshToken(user.refreshToken)
.then((res) => {
const { accessToken } = res.data.data;
Client.defaults.headers.common.Authorization = accessToken;
// update local storage
updateLocalStorageAccessToken(accessToken);
return Client(originalRequest);
})
.catch((err) => {
console.log(err);
if (err.response.status === 401) {
localStorage.setItem('user', null);
history.push('/login');
}
return Promise.reject(err);
});
}
history.push('/login');
return Promise.reject(error);
}
);
export const useAxios = (axiosParams, isAuto = true) => {
const [response, setResponse] = useState(undefined);
const [error, setError] = useState('');
const [loading, setLoading] = useState(true);
const fetchData = async (params) => {
try {
const result = await Client.request({
...params,
method: params.method || 'GET',
headers: {
accept: 'application/json',
},
});
setResponse(result.data);
} catch (error) {
setError(error);
} finally {
setLoading(false);
}
};
useEffect(() => {
if (isAuto) fetchData(axiosParams);
}, [axiosParams, isAuto]); // execute once only
return { fetch: () => fetchData(axiosParams), response, error, loading };
};

response的拦截器中,检查是否有错误。我将保留一个状态,其中包含先前的成功调用,实现你想要的-之后,创建一个拦截器的请求,检查是否发生了错误,如果是,取消请求:

axios.interceptors.request.use((req: AxiosRequestConfig) => {
if(error){
throw new axios.Cancel('Operation canceled due to previous failure.');
}
else {
return req
}
})

参见:Axios:如何在请求拦截器内正确取消请求?

相关内容

最新更新