react router 4 页面跳转前 axios中断未完成的请求
思路:
1.首先利用 axios拦截器 自动检测未完成的请求
2.路由跳转前判断,react-router4提供了一个Prompt组件,react Router 4 版本Router组件(我这里是HashRouter)提供了一个属性 getUserConfirmation ,可在该方法上进行处理,这样就能在切页面的时候自动获取到变化,(tab选项卡也可以)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | function App() { return ( <Provider store={store}> <HashRouter getUserConfirmation={getConfirmation}> <LocaleProvider> <> <Prompt message= "Are you sure you want to leave?" ></Prompt> <Main /> </> </LocaleProvider> </HashRouter> </Provider > ); } ReactDOM.render( <App /> , document.getElementById( 'app' ) ); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | const allPendingRequestsRecord = []; const pending = {}; function removeAllPendingRequestsRecord() { allPendingRequestsRecord && allPendingRequestsRecord.forEach((func) => { func( 'page changes' ); // 取消请求 }); allPendingRequestsRecord.splice(0); // 移除所有记录 } const getConfirmation = (message, callback) => { removeAllPendingRequestsRecord(); callback( true ); }; const removePending = (key, isRequest = false ) => { if (pending[key] && isRequest) { pending[key]( '取消重复请求' ); } delete pending[key]; }; axios.interceptors.request.use( config => { // 在请求发送前执行一下取消操作,防止连续点击重复发送请求(例如连续点击2次按钮) const reqData = config.url + config.method; removePending(reqData, true ); // 设置请求的 cancelToken config.cancelToken = new axios.CancelToken(c => { pending[reqData] = c; allPendingRequestsRecord.push(c); }); return config; }, error => { Promise.reject(error); } ); axios.interceptors.response.use( response => { return response; }, error => { throw new Error( '!接口请求错误' ); } );const CancelToken = axios.CancelToken; let cancel = null ; function * removeAllPendingRequestsRecord() { //正在请求的接口中断函数 cancel && cancel(); } const response = yield call(axios.post, url, payload, { cancelToken: new CancelToken( function executor(c) { cancel = c; })}); |
如果项目中业务逻辑需要页面单独处理可以在组件封装中处理,添加cancelToken函数,
import axios from 'axios';
const CancelToken = axios.CancelToken;
const allPendingRequestsRecord = [];
const query = (options = {}) => axios({
method: 'get',
...options,
headers: {
'Authorization': 'bearer ' + (localStorage.getItem('authData') || ''),
...options.headers,
},
cancelToken: new CancelToken((c) => {
allPendingRequestsRecord.push(c);
}),
}).then(data => data.data || {}).catch(res => {
console.log('cancelReq', res);
});
const request = (options) => query(options);
request.removeAllPendingRequestsRecord = () => {
allPendingRequestsRecord && allPendingRequestsRecord.forEach((cancel) => {
cancel && cancel(); // 取消请求
});
allPendingRequestsRecord.splice(0);
};
request.get = (url, options = {}) => query({ url, ...options });
如果单独在saga中使用axios,
如果单独在saga中使用axios,
在业务逻辑处理中调用removeAllPendingRequestsRecord函数。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步