useEffect 中取消 axios 请求未运行

jus*_*guy 3 reactjs axios react-hooks

我正在尝试取消 axios 请求,但只取得了部分成功。当我发出 GET 请求时,我有一个返回 Promise 的函数:

const getCards = (token) => {
  const URL = isDev
    ? "https://cors-anywhere.herokuapp.com/https://privacy.com/api/v1/card"
    : "https://privacy.com/api/v1/card";
  const config = {
    headers: {
      Authorization: `Bearer ${token}`,
    },
    cancelToken: source.token,
  };

  return axios.get(URL, config);
};
Run Code Online (Sandbox Code Playgroud)

我在里面调用这个函数updateCards(),如下所示:

const updateCards = async () => {
  console.log("Updating Cards");

  setCards([]);
  setStarted(true);
  setLoading(true);

  let response = await getCards(token).catch((thrown) => {
    if (axios.isCancel(thrown)) {
      console.error("[UpdateCards]", thrown.message);
    }
  });

  /**
   * response is undefined when we cancel the request on unmount
   */

  if (typeof response === "undefined") return console.log("Undefined");

  console.log("Got Response from UpdateCards", response);

  setLoading(false);
};
Run Code Online (Sandbox Code Playgroud)

我在 useEffect 挂钩中取消了我的请求,如下所示:

useEffect(() => {
    return () => {
        source.cancel()
    }
}, [])
Run Code Online (Sandbox Code Playgroud)

我在状态声明下设置了 CancelToken,如下所示:

const CancelToken = axios.CancelToken;
const source = CancelToken.source();
Run Code Online (Sandbox Code Playgroud)

我的问题是,如果我在 useEffect() 内部调用 updateCards() 函数,我可以很好地取消它,但如果我使用按钮调用同一函数,则不会运行取消。我到处寻找,找到的唯一解决方案是我必须在 useEffect() 挂钩中调用我的请求,但这不是我想要做的事情。我该从这里去哪里?

以下是我看过的资源:

https://github.com/axios/axios#cancellation

https://medium.com/@selvaganesh93/how-to-clean-up-subscriptions-in-react-components-using-abortcontroller-72335f19b6f7

无法通过 CancelToken 取消 Axios post 请求

Ros*_*len 5

要拥有一个位置来存储行为类似于组件实例变量useRef的变量,您可以使用. 它是一个容器,可以装任何你想要的东西。您可以将 CancelToken 存储在其中:

function Privacy(props) {
  const source = useRef(null);

  function getSource() {
    if (source.current == null) {
      const CancelToken = axios.CancelToken;
      source.current = CancelToken.source();
    }
    return source.current;
  }

  useEffect(() => {
    return () => {
      if (source.current != null) source.current.cancel();
    }
  }, [])

  // call `getSource()` wherever you need the Axios source
}
Run Code Online (Sandbox Code Playgroud)