使用axios取消卸载时的异步请求

时间:2017-09-08 06:35:57

标签: reactjs axios

对于某些获取请求,我有多个带有axios插件的组件。我需要一些帮助来取消反应js中组件卸载事件中axios的所有xhr请求。但axios取消代码不起作用。它返回我cancel()不是函数错误。

代码示例: -

import axios from 'axios';


var CancelToken = axios.CancelToken;
var cancel;

axios.get('abc/xyz', {
  cancelToken: new CancelToken(function executor(c) {
    // An executor function receives a cancel function as a parameter
    cancel = c;
  })
});

// cancel the request
cancel();

请帮我在axios中实施取消请求。

感谢。

4 个答案:

答案 0 :(得分:0)

除非您使用RxJS,否则您无法取消请求。我建议你为此目的使用redux-observable。请查看this以获取更多信息。您必须在Epic中使用takeUntil运算符,并在取消操作触发时执行取消操作。这是上述资源给出的示例代码。

import { ajax } from 'rxjs/observable/dom/ajax';

const fetchUserEpic = action$ =>
  action$.ofType(FETCH_USER)
    .mergeMap(action =>
      ajax.getJSON(`/api/users/${action.payload}`)
        .map(response => fetchUserFulfilled(response))
        .takeUntil(action$.ofType(FETCH_USER_CANCELLED))
    );

答案 1 :(得分:0)

使用faxios代替axios

 let req = faxios()
  .url('abc/xyz')

  .GET

  .then(res => {})
  .catch(err => {});

// canceling...
req.cancel();

答案 2 :(得分:0)

这很简单。在componentDidMount中创建请求,然后在componentWillUnmount中取消请求。将网址替换为现有的JSON文件,此代码段将按预期工作:

class MyComponent extends Component {
  constructor (props) {
    super(props)

    this.state = {
      data: []
    }
  }

  componentDidMount () {
    this.axiosCancelSource = axios.CancelToken.source()

    axios
      .get('data.json', { cancelToken: this.axiosCancelSource.token })
      .then(response => {
        this.setState({
          data: response.data.posts
        })
      })
      .catch(err => console.log(err))
  }

  componentWillUnmount () {
    console.log('unmount component')
    this.axiosCancelSource.cancel('Component unmounted.')
  }

  render () {
    const { data } = this.state

    return (
     <div>
          {data.items.map((item, i) => {
            return <div>{item.name}</div>
          })}
      </div>
    )
  }
}

答案 3 :(得分:0)

除了@taseenb 响应之外,如果您使用 React 钩子,这里有一个示例。

使用 useHook检测路线变化。然后,在路由卸载时使用 TOKEN 取消请求并生成新的 TOKEN 以进行新的请求。有关更多详细信息,请参阅 Axios 文档 (https://github.com/axios/axios)。

Route.tsx 文件

import React, { useEffect } from 'react';
import { Route, RouteProps, useLocation } from 'react-router-dom';
import API from 'src/services/service';

const CustomRoute = (props: RouteProps) => {
  const location = useLocation();

  // Detect Route Change
  useEffect(() => {
    handleRouteChange();

    return () => {
      handleRouteComponentUnmount();
    };
  }, [location?.pathname]);

  function handleRouteChange() {
    // ...
  }

  function handleRouteComponentUnmount() {
    API.finishPendingRequests('RouteChange');
  }

  return <Route {...props} />;
};

export default CustomRoute;

Service.ts 文件

import { Response } from 'src/models/request';
import axios, {AxiosInstance, AxiosResponse } from 'axios';

const ORIGIN_URL = 'https://myserver.com'
const BASE_URL = ORIGIN_URL + '/api';
let CANCEL_TOKEN_SOURCE = axios.CancelToken.source();
    
function generateNewCancelTokenSource() {
  CANCEL_TOKEN_SOURCE = axios.CancelToken.source();
}

export const axiosInstance: AxiosInstance = axios.create({
  baseURL: BASE_URL,
});

const API = {
  get<DataResponseType = any>(
    endpoint: string,
  ): Promise<AxiosResponse<Response<DataResponseType>>> {
    return axiosInstance.get<Response<DataResponseType>>(endpoint, {
      cancelToken: CANCEL_TOKEN_SOURCE.token,
    });
  },

  // ...Another Functions

  finishPendingRequests(cancellationReason: string) {
    CANCEL_TOKEN_SOURCE.cancel(cancellationReason);
    generateNewCancelTokenSource();
  },
};

export default API;