【问题标题】:How to use Axios cancelToken in interceptors?如何在拦截器中使用axios cancelToken?
【发布时间】:2020-09-28 04:06:30
【问题描述】:

在 ReactJs 中,我使用 Axios 从 API 获取数据。当我尝试发出重复请求时,我需要使用 cancelToken。例如:假设我在完成 Axios 请求之前就在主页上,我被要求访问 About 页面。结果,React 应用程序显示内存泄漏错误。所以,我的计划是在axios拦截器中设置axios cancelToken。我试过了,但它不适合我。

requestApi.js

import axios from 'axios';

const requestApi = axios.create({
  baseURL: process.env.REACT_APP_API_URL
});
const source = axios.CancelToken.source();

requestApi.interceptors.request.use(async config => {
  const existUser = JSON.parse(localStorage.getItem('user'));
  const token = existUser && existUser.token ? existUser.token : null;
  if (token) {
    config.headers['Authorization'] = token;
    config.headers['cache-control'] = 'no-cache';
  }

  config.cancelToken = source.token;

  return config;
}, error => {
  return Promise.reject(error);
});

requestApi.interceptors.request.use(async response => {
  throw new axios.Cancel('Operation canceled by the user.');
  return response;
}, error => {
  return Promise.reject(error);
});

export default requestApi;

仪表板.js

import requestApi from './requestApi';

useEffect(() => {
  const fetchData = async () => {
    try {
      const res = await requestApi.get('/dashboard');
      console.log(res.data);
    } catch (error) {
      console.log(error);
    }
  }

  fetchData();
}, []);

【问题讨论】:

  • 你找到解决办法了吗?
  • 我在同一条船上。

标签: reactjs axios token


【解决方案1】:

以防您仍然需要它或其他人来寻找它。这就是它对我的工作方式。

import axios from "axios";

// Store requests
let sourceRequest = {};

const requestApi = axios.create({
  baseURL: process.env.REACT_APP_API_URL
});

requestApi.interceptors.request.use(
  async config => {
    const existUser = JSON.parse(localStorage.getItem("user"));
    const token = existUser && existUser.token ? existUser.token : null;
    if (token) {
      config.headers["Authorization"] = token;
      config.headers["cache-control"] = "no-cache";
    }

    return config;
  },
  error => {
    return Promise.reject(error);
  }
);

requestApi.interceptors.request.use(
  request => {
    // If the application exists cancel
    if (sourceRequest[request.url]) {
      sourceRequest[request.url].cancel("Automatic cancellation");
    }

    // Store or update application token
    const axiosSource = axios.CancelToken.source();
    sourceRequest[request.url] = { cancel: axiosSource.cancel };
    request.cancelToken = axiosSource.token;

    return request;
  },
  error => {
    return Promise.reject(error);
  }
);

export default requestApi;

【讨论】:

    【解决方案2】:

    这可能不是一个稳定的解决方案,但我们可以使用一些魔法来制作一个组件,该组件会在组件卸载时终止在内部运行的异步代码(包括请求)。无需令牌即可使其工作。见Live Demo

    import React, { useState } from "react";
    import { useAsyncEffect, E_REASON_UNMOUNTED } from "use-async-effect2";
    import { CanceledError } from "c-promise2";
    import cpAxios from "cp-axios";
    
    function* makeAPICall(url) {
      const existUser = JSON.parse(localStorage.getItem("user"));
      const token = existUser && existUser.token ? existUser.token : null;
      return yield cpAxios(url, {
        headers: {
          Authorization: token,
          "cache-control": "no-cache"
        }
      });
    }
    
    export default function TestComponent(props) {
      const [text, setText] = useState("");
    
      const cancel = useAsyncEffect(
        function* () {
          console.log("mount");
    
          this.timeout(props.timeout);
    
          try {
            setText("fetching...");
            const response = yield* makeAPICall(props.url);
            setText(`Success: ${JSON.stringify(response.data)}`);
          } catch (err) {
            CanceledError.rethrow(err, E_REASON_UNMOUNTED); //passthrough
            setText(`Failed: ${err}`);
          }
    
          return () => {
            console.log("unmount");
          };
        },
        [props.url]
      );
    
      return (
        <div className="component">
          <div className="caption">useAsyncEffect demo:</div>
          <div>{text}</div>
          <button onClick={cancel}>Abort</button>
        </div>
      );
    }
    

    【讨论】:

      猜你喜欢
      • 2019-03-15
      • 2019-06-26
      • 2021-04-18
      • 2018-11-01
      • 2020-09-27
      • 2019-04-28
      • 2023-01-10
      • 2023-01-21
      • 2021-05-04
      相关资源
      最近更新 更多