我想使用axios请求和响应拦截器在每个请求前后显示/隐藏加载程序。为此,我使用redux来维护加载器状态,但我不能在拦截器文件中使用useDispatch
和useHistory
挂钩。
所以我想我将不得不从index.js传递它,但我再次得到同样的错误。
钩子调用无效。钩子只能在函数组件的内部调用
拦截器代码。
const handler401 = (dispatch, history) => {
dispatch(authActions.logOut);
history.push(LOGIN);
};
const handler500 = (dispatch, error) => {
let message = L('global.error');
if (error.response && error.response.data?.error) {
message = error.response.data.error;
}
dispatch(
uiActions.showNotification({
title: L('global.errorTitle'),
message,
status: 'error',
})
);
};
const setupInterceptors = (dispatch, history) => {
request.api.interceptors.request.use(
(successfulReq) => {
console.log('show loader start');
dispatch(uiActions.showLoader());
return successfulReq;
},
(error) => {
dispatch(uiActions.hideLoader());
return Promise.reject(error);
}
);
request.api.interceptors.response.use(
(response) => {
dispatch(uiActions.hideLoader());
return response;
},
(error) => {
console.log('hide loader start');
dispatch(uiActions.hideLoader());
if (error.response.status === 401) {
handler401(dispatch, history);
} else {
handler500(dispatch, error);
}
return Promise.reject(error);
}
);
};
我已经在index.js 中注册了这个拦截器
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider, useDispatch } from 'react-redux';
import { BrowserRouter, useHistory } from 'react-router-dom';
import App from './App';
import reportWebVitals from './reportWebVitals';
import store from './store/index';
import setupInterceptors from './services/interceptorService';
const history = useHistory();
const dispatch = useDispatch();
setupInterceptors(dispatch, history);
ReactDOM.render(
<Provider store={store}>
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>
</Provider>,
document.getElementById('root')
);
reportWebVitals();
如何将以上两个钩子传递给我的拦截器?
不确定你所做的是否正确,但如果你真的想这样做,你必须只在React组件内部传递调度和历史记录函数。
建议你这样做:
const App = () => {
const dispatch = useDispatch()
const history = useHistory()
useEffect(() => {
const eventHandlerFn = (success) => {
dispatch(myAction.doSomething())
history.push("/yay")
}
request.api.interceptors.request.use(eventHandlerFn)
return () => {
request.api.interceptors.request.eject(eventHandlerFn);
}
}, [])
return (
<div>
<h1>My App</h1>
</div>
)
}
在这里,我在具有[]
依赖项的useEffect中向axios拦截器添加了事件处理程序函数,因此它只在App
装载上运行,这意味着它在整个应用程序中只运行一次。
由于我是在React组件中完成的,所以我可以将挂接的东西,如dispatch
和history
,传递给setupInterceptor
函数。
useEffect返回一个函数,在应用程序卸载时清理拦截器事件处理程序。