Skip to content

Instantly share code, notes, and snippets.

@martinmckenna
Last active February 7, 2019 15:00
Show Gist options
  • Save martinmckenna/51604f98eedaef36432ffe0b99a7eab3 to your computer and use it in GitHub Desktop.
Save martinmckenna/51604f98eedaef36432ffe0b99a7eab3 to your computer and use it in GitHub Desktop.
Data Fetching with Hooks and Axios Cancellable Requests
import React, { useEffect, useState } from 'react';
import Axios from 'axios'
/**
* returns an object which contains
* both the fetch request
* and the function that will cancel the in-flight request
*/
const fetchData = () => {
const source = Axios.CancelToken.source();
return {
request: () => Axios('https://site.com/endpoint', {
method: 'GET',
cancelToken: source.token
}).then(response => response.data),
cancel: source.cancel
}
}
/**
* intercept all network requests and add a "wasCancelled"
* flag if the request was cancelled mid-flight
*/
Axios.interceptors.response.use(
(response) => response,
(err: AxiosError): Promise<APIError[]> => {
/** was this a result of an Axios cancel invocation */
const wasCancelled = Axios.isCancel(err);
return err.response && !wasCancelled
? Promise.reject(err.response)
: Promise.reject([
{
reason: 'There was an error',
wasCancelled
}
]);
}
);
const MyComponent = (props: MyProps) => {
const [loading, updateLoading] = useState<boolean>(false);
const [error, updateError] = useState<APIError[] | undefined >(undefined);
const [fetchedData, updateFetchedData] = useState<DataType | undefined>(undefined);
useEffect(() => {
/** set loading to true, display spinner or whatever */
updateLoading(true);
fetchData().request()
.then((response) => {
updateLoading(false);
updateTemplateData(response)
})
.catch((err: APIError[]) => {
/**
* if the request was cancelled mid-flight, early return
* the idea is to prevent setting state on unmounted components
*/
if(err[0].wasCancelled) { return; }
updateLoading(false);
updateError(err)
})
return () => {
/** on unmount, cancel the request if it is in-flight */
fetchData.cancel();
}
}, [])
...
...
...
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment