The easiest way to create HTTP requests in React.js

Soroush Chehresa
4 min readAug 15, 2020

Always when we are developing a web application with React, we have many options to create HTTP requests which using some of them could be complicated and time-consuming.

For resolving this issue I created a simple React component with TypeScript as an npm package named axios-react to make HTTP requests so easier in React applications.

🌐 axios-react

This package is an HTTP client component for React with child function callback to create async requests in render based on Axios.

If you are new to React or if you want to create an application with React fast, you can use this module to speed your development up!

🤔 How Axios React works?

Using axios-react is so easy, you just need to wrap your components with this module. Let’s see axios-react usage by the following steps:

At first, you need to install this package:

$ yarn add axios-react# or$ npm i -S axios-react

And then, you can make your HTTP request like this:

import React from 'react';
import Request from 'axios-react';

const Demo = () => (
<Request
config={{
method: 'get',
url: 'https://jsonplaceholder.typicode.com/todos/1',
}}
>
{({ loading, response, error, refetch, networkStatus }) => (
<div>
{networkStatus && <span>{networkStatus}</span>}
{loading && <span>Loading...</span>}
{error && <span>{error.response.data}</span>}
{response && <h3>{response.data.title}</h3>}
<button onClick={refetch}>Refetch!</button>
</div>
)}
</Request>
);

An online real example:

https://stackblitz.com/edit/react-2et9ls

💡 How did axios-react implement?

Import modules:

import { 
useState,
useEffect,
ReactChildren,
ReactChild,
} from 'react';
import axios, { AxiosResponse, AxiosError, AxiosRequestConfig } from 'axios';
import isOnline from 'is-online';
import root from 'window-or-global';

Types definition:

interface ChildrenProps {  
loading: boolean,
error: AxiosError<any> | null,
response: AxiosResponse<any> | null,
refetch: () => void,
networkStatus: string | null;
}
interface Props {
children: ((props: ChildrenProps) => ReactNode) | ReactNode;
skip?: boolean,
config: AxiosRequestConfig,
}

States definition:

const [loading, setLoading] = useState<boolean>(false);  
const [error, setError] = useState<AxiosError<any> | null>(null); const [response, setResponse] = useState<AxiosResponse<any> | null>(null);
const [networkStatus, setNetworkStatus] = useState<string | null>(null);

Check network status method implementation:

useEffect((): void => {
checkNetworkConnection();
}, []);
const checkNetworkConnection = (): void => {
if ((typeof document != 'undefined') && root && isOnline) {
root.addEventListener('offline', () => {
isOnline({ timeout: 1000 })
.then(online => {
if (!online) {
setNetworkStatus('offline');
}
});
});
root.addEventListener('online', () => {
isOnline({ timeout: 1000 })
.then(online => {
if (online) {
setNetworkStatus('online');
}
});
});
isOnline({ timeout: 1000 })
.then(online => {
if (
(online && networkStatus !== 'online')
|| (!online && networkStatus !== 'offline')
) {
setNetworkStatus(online ? 'online' : 'offline');
}
});
}
};

Fetch method implementation:

useEffect((): void => {
// ...
if (!skip) {
fetch();
}
}, []);
const fetch = (): void => {
if (config) {
setLoading(true);
axios(config)
.then((response: AxiosResponse<any>) => {
setResponse(response);
setLoading(false);
})
.catch((error: AxiosError<any>) => {
setError(error);
setLoading(false);
});
}
};

Return child function callback implementation:

return children({ 
loading,
error,
response,
refetch: fetch,
networkStatus,
});

That’s it. EASY EASY TAMAM TAMAM ;)

import { 
useState,
useEffect,
ReactChildren,
ReactChild,
} from 'react';
import axios from 'axios';
import isOnline from 'is-online';
import root from 'window-or-global';

interface ChildrenProps {
loading: boolean,
error: AxiosError<any> | null,
response: AxiosResponse<any> | null,
refetch: () => void,
networkStatus: string | null;
}
interface Props {
children: ((props: ChildrenProps) => ReactNode) | ReactNode;
skip?: boolean,
config: AxiosRequestConfig,
}

export default (
{
children,
skip,
config,
}: Props,
) => {
const [loading, setLoading] = useState<boolean>(false);
const [error, setError] = useState<AxiosError<any> | null>(null);
const [response, setResponse] = useState<AxiosResponse<any> | null>(null);
const [networkStatus, setNetworkStatus] = useState<string | null>(null);

useEffect((): void => {
checkNetworkConnection();
if (!skip) {
fetch();
}
}, []);

const checkNetworkConnection = (): void => {
if ((typeof document != 'undefined') && root && isOnline) {
root.addEventListener('offline', () => {
isOnline({ timeout: 1000 })
.then(online => {
if (!online) {
setNetworkStatus('offline');
}
});
});
root.addEventListener('online', () => {
isOnline({ timeout: 1000 })
.then(online => {
if (online) {
setNetworkStatus('online');
}
});
});
isOnline({ timeout: 1000 })
.then(online => {
if (
(online && networkStatus !== 'online')
|| (!online && networkStatus !== 'offline')
) {
setNetworkStatus(online ? 'online' : 'offline');
}
});
}
};

const fetch = (): void => {
if (config) {
setLoading(true);
axios(config)
.then((response) => {
setResponse(response);
setLoading(false);
})
.catch((error) => {
setError(error);
setLoading(false);
});
}
};

return children({
loading,
error,
response,
refetch: fetch,
networkStatus,
});
};

🔗 Links

Source code:

npm package:

Thanks for your regards 🙏

--

--