How can i call axios abort function synchronously

Viewed 139

currently, I'm trying to call Axios abort function as soon as I got data. I'm using Axios as interval call API, so I want to abort the request as soon as I get data because of making it stop properly.

however, setState is Asynchronously so I can not get the result that I expected.

so I want to know how to do that.

here is my code:

const controller = new AbortController();

  const CancelToken = axios.CancelToken;
  const source = CancelToken.source();

  const getAPI = useCallback(async () => {
    await axios
      .get(convert.GET_API_URL, {
        headers: convert.Header,
        cancelToken: source.token,
        signal: controller.signal,
      })
      .then(response => {
        setAPI_DATA(response.data);
        setSpinner(false);
        controller.abort();
        source.cancel();
      })

      .catch(error => {
        setSpinner(false);
      });
  }, [API_DATA, convert, spinner]);

  useInterval(
    () => {
      getAPI();
    },
    apiStart ? convert?.API_Read_Speed : null
  );

useInterval

import { useEffect } from "react";
import { useRef } from "react";

const useInterval = (callback, delay) => {
  const savedCallback = useRef(callback);

  useEffect(() => {
    savedCallback.current = callback;
  }, [callback]);

  useEffect(() => {
    const tick = () => {
      savedCallback.current();
    };

    if (delay !== null) {
      const id = setInterval(tick, delay);
      return () => clearInterval(id);
    }
  }, [delay]);
};

export default useInterval;

1 Answers

In most cases you should avoid setInterval under React's declarative paradigm. Instead, design your components to handle any possible state on every render.

This is a basic example to illustrate a common data fetching pattern in React.

Fetch data inside of a useEffect() hook. Because the dependency array is empty ([]), only one API request will be made.

import { useState, useEffect } from "react";
import { Axios } from "axios";

const useData = () => {
  const [data, setData] = useData(null);
  const [error, setError] = useState(null);

  useEffect(() => {
    Axios.get("https://my.api.com/data")
      .then((response) => setData(response.data))
      .catch((error) => setError(error));
  }, []);

  return { data, error, loading: !data && !error };
};

export default function MyComponent() {
  const { data, loading, error } = useData();

  if (loading) return <div>Loading...</div>;

  if (error) return <div>{JSON.stringify(error)}</div>;

  return <div>{JSON.stringify(data)}</div>;
}
Related