DEV Community

Discussion on: useAxios : A simple custom hook for calling APIs using axios

Collapse
 
ecyrbe profile image
ecyrbe • Edited

Hello,

here is a reviewed code for final solution :

import { useState, useEffect } from 'react';
import axios from 'axios';

axios.defaults.baseURL = 'https://jsonplaceholder.typicode.com';

/**
 fixed :
  - no need to JSON.stringify to then immediatly do a JSON.parse
  - don't use export defaults, because default imports are hard to search for
  - axios already support generic request in one parameter, no need to call specialized ones
**/
export const useAxios = (axiosParams) => {
    const [response, setResponse] = useState(undefined);
    const [error, setError] = useState('');
    const [loading, setloading] = useState(true);

    const fetchData = async (params) => {
      try {
       const result = await axios.request(params);
       setResponse(result.data);
       } catch( error ) {
         setError(error);
       } finally {
         setLoading(false);
       }
    };

    useEffect(() => {
        fetchData(axiosParams);
    }, []); // execute once only

    return { response, error, loading };
};
Enter fullscreen mode Exit fullscreen mode

and to use it :

import { useAxios } from 'axioshook';

const App = () => {
    const { response, loading, error } = useAxios({
        method: 'POST',
        url: '/posts',
        headers: { // no need to stringify
          accept: '*/*'
        },
        data: {  // no need to stringify
            userId: 1,
            id: 19392,
            title: 'title',
            body: 'Sample text',
        },
    });

    return (
        <div className='App'>
            <h1>Posts</h1>

            {loading ? (
                <p>loading...</p>
            ) : (
                <div>
                    {error && (
                        <div>
                            <p>{error.message}</p>
                        </div>
                    )}
                    <div> {
                      // no need to use another state to store data, response is sufficient
                      response && <p>{response.id}</p>
                    }
                    </div>
                </div>
            )}
        </div>
    );
};
Enter fullscreen mode Exit fullscreen mode
Collapse
 
imervinc profile image
👺Mervyn

Exactly what I was thinking while reading the post XD. And maybe wrap this in React Query for an even juicier hook!

Collapse
 
ecyrbe profile image
ecyrbe

You can get it here :

httpss://github.com/ecyrbe/react-axios-query

It's juste a wrapper. Really simple.

Thread Thread
 
ayoubkhan558 profile image
Muhammad Ayoub Khan
Collapse
 
bernasantolin profile image
Antolin B. Bernas Jr.

sir what if the structure has axios interceptor and header is with bearer token?

Collapse
 
matek075 profile image
Matek

Hi, small fix:
here const [loading, setloading] = useState(true);
to const [loading, setLoading] = useState(true);

upperCase "L"

Greetings

Collapse
 
peng profile image
Peng

Wow

Collapse
 
kamrulhasan12345 profile image
Mohammad Kamrul Hasan

A correction:
Add axiosParams to the empty list in the second param of the useEffect hook. This will remove a dependency error

Collapse
 
seetaram_yadav profile image
Seetaram Yadav • Edited

There is small syntax error in losing callback. instead of setloading it should be setLoading. `import { useState, useEffect } from 'react';
import axios from 'axios';

axios.defaults.baseURL = 'jsonplaceholder.typicode.com';

/**
fixed :

  • no need to JSON.stringify to then immediatly do a JSON.parse
  • don't use export defaults, because default imports are hard to search for
  • axios already support generic request in one parameter, no need to call specialized ones **/

`import { useState, useEffect } from 'react';
import axios from 'axios';

axios.defaults.baseURL = 'jsonplaceholder.typicode.com';

/**
fixed :

  • no need to JSON.stringify to then immediatly do a JSON.parse
  • don't use export defaults, because default imports are hard to search for
  • axios already support generic request in one parameter, no need to call specialized ones
    **/
    export const useAxios = (axiosParams) => {
    const [response, setResponse] = useState(undefined);
    const [error, setError] = useState('');
    const [loading, setLoading] = useState(true);

    const fetchData = async (params) => {
    try {
    const result = await axios.request(params);
    setResponse(result.data);
    } catch( error ) {
    setError(error);
    } finally {
    setLoading(false);
    }
    };

    useEffect(() => {
    fetchData(axiosParams);
    }, []); // execute once only

    return { response, error, loading };
    };`

Collapse
 
hey_yogini profile image
Yogini Bende

This is a really good optimisation, specially the axios.request 👏
Two points to consider here -

  1. JSON.stringify and JSON.parse was used to avoid possibility of any errors.
  2. An extra state was added in the App component, as we may need to process some data coming from the api response (which is mostly the case).

Thanks for sharing this 🙌

Some comments have been hidden by the post's author - find out more