react router 4 頁面跳轉前 axios中斷未完成的請求


思路:
1.首先利用 axios攔截器 自動檢測未完成的請求
2.路由跳轉前判斷,react-router4提供了一個Prompt組件,react Router 4 版本Router組件(我這里是HashRouter)提供了一個屬性 getUserConfirmation ,可在該方法上進行處理,這樣就能在切頁面的時候自動獲取到變化,(tab選項卡也可以)

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')
);

  

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('!接口請求錯誤');
  }
);
 
         


如果項目中業務邏輯需要頁面單獨處理可以在組件封裝中處理,添加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,
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; })});
在業務邏輯處理中調用 removeAllPendingRequestsRecord函數。

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM