【问题标题】:React - requests cancellation on page changeReact - 请求取消页面更改
【发布时间】:2019-03-07 13:17:06
【问题描述】:

我正在使用axios 获取/发布数据到我的服务器,我当前的方法如下所示:

1。使用 redux-thunk 的 redux 操作发出请求,操作如下所示:

export const getRecords = () => (dispatch, getState, { api }) => {
  const type = GET_RECORDS_LOAD;
  return dispatch({
    type,
    promise: api.Records.get({ type }),
  });
};

2。 api.Record.get 看起来像这样:

import _ from 'lodash';
import axios from 'axios';

const APIInstance = axios.create({
  baseURL: process.env.API_URL,
});

const getCancelToken = id => new axios.CancelToken((c) => {
  const cancel = c;
  const cancelationTokens = _.get(window, 'cancelationTokens', {});
  cancelationTokens[id] = cancel;
  _.set(window, 'cancelationTokens', cancelationTokens);
});

const api = {
  Records: {
    get: ({ type }) => APIInstance.get('/my-records', { cancelToken: getCancelToken(type) }),
  },
};

在这里,我根据 redux 操作类型创建了一个 cancelToken,并将其存储在 window.cancelationTokens 对象中,因此可以从应用程序的任何位置取消它们。

3。取消componentWillUnmount

import * as Types from './path/to/action/types';

const cancelToken = (type) => {
  const cancel = _.get(window, `cancelationTokens.${type}`);
  if (!cancel) return;
  cancel();
}

componentWillUnmount() {
  cancelToken(Types.GET_RECORDS_LOAD);
  // If more request I have to cancel them manually...
}

如您所见,这种方法没有大问题,但如果我在一个页面上执行大量请求,我必须在 componentWillUnmount 中手动取消它们。

我的问题:

  1. 如果用户在我的应用中更改页面,是否有办法自动取消正在进行的请求?
  2. 如果是 - 这是执行此操作的正确方法,还是有更简单的方法来取消请求?

【问题讨论】:

    标签: javascript reactjs axios


    【解决方案1】:

    所以,我所做的是创建了一个名为 RequestCancelation 的类,它使用 history 包。可以根据传递的动作类型取消请求,也可以根据history.location.pathname取消请求。

    RequestCancelation.js

    import _ from 'lodash';
    import axios from 'axios';
    import createHistory from 'history/createBrowserHistory';
    
    // In my case the history is imported from another file, as I pass
    // it to the `Router` from `react-router-dom`. For the purpose of this
    // example I created the history here.
    const history = createHistory();
    
    class RequestCancelation {
      static constants = {
        cancelationTokens: 'CANCELATION_TOKENS',
      }
    
      getTokens() {
        return _.get(window, RequestCancelation.constants.cancelationTokens, {});
      }
    
      setTokens(tokens) {
        return _.set(window, RequestCancelation.constants.cancelationTokens, tokens);
      }
    
      deleteTokens(key) {
        if (!key) return undefined;
        delete window[RequestCancelation.constants.cancelationTokens][key];
        return this.getTokens();
      }
    
      getLocationKey() {
        return _.get(history, 'location.pathname');
      }
    
      getCancelToken(type) {
        return new axios.CancelToken((c) => {
          const cancel = c;
          if (typeof window === 'undefined') return;
          const tokens = this.getTokens();
          if (type) {
            tokens[type] = cancel;
          } else {
            const key = this.getLocationKey();
            if (!key) return;
            if (!tokens[key]) tokens[key] = [];
            tokens[key].push(cancel);
          }
          this.setTokens(tokens);
        });
      }
    
      cancelRequest(type) {
        if (!type) {
          return console.warn('#cancelRequest - please specify \'type\'');
        }
        if (typeof window === 'undefined') return undefined;
        const tokens = this.getTokens();
        const cancel = tokens[type];
        if (!cancel) return undefined;
        cancel();
        return this.deleteTokens(type);
      }
    
      cancelRequests() {
        if (typeof window === 'undefined') return undefined;
        const tokens = this.getTokens();
        const key = this.getLocationKey();
        if (!key) return undefined;
        const cancels = tokens[key];
        if (!cancels) return undefined;
        cancels.forEach(cancel => cancel());
        return this.deleteTokens(key);
      }
    
      clearTokens() {
        if (typeof window === 'undefined') return undefined;
        window[RequestCancelation.constants.cancelationTokens] = {};
        return this.getTokens();
      }
    }
    
    const cancelation = new RequestCancelation();
    
    export default cancelation;
    

    希望这可以帮助某人,也许有人可以改进它:)

    也可作为gist 使用。

    【讨论】:

      猜你喜欢
      • 2017-12-11
      • 2011-10-18
      • 2019-08-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-28
      相关资源
      最近更新 更多