Section 1: Setting up React Query
React Query is a powerful library that simplifies data fetching and state management in React applications. It provides an elegant way to handle asynchronous operations and cache data for improved performance. Let's get started by setting up React Query in our project.
To install React Query, you can use the following command:
npm install @tanstack/react-query
Once installed, you can import the necessary dependencies:
import { useQuery } from "@tanstack/react-query";
import Cookies from "js-cookie";
The useQuery
hook is provided by React Query and allows us to fetch data from an API. We'll also be using the Cookies
library to handle authentication tokens.
Now, let's take a look at the fetchApi
function:
const fetchApi = async () => {
const response = await request({
url: "/your-end-point",
method: "GET",
});
return response?.data?.data;
};
Section 2: Creating the Custom Hook
Custom hooks are a powerful concept in React that allows us to encapsulate and reuse logic across multiple components. Let's create a custom hook called useUsers
that leverage React Query to fetch user data.
const GET_API_NAME = 'your-api-name';
const useApiQuery = () => {
const token = Cookies.get("token");
const { isLoading, isError, data, error, refetch } = useQuery(
[GET_API_NAME],
fetchApi, {
enabled: !!token,
onError: (error) => {
console.error(error);
},
}
);
return { isLoading, isError, data, error, refetch };
};
export { useApiQuery };
The useApiQuery
hook uses the useQuery
hook from React Query to handle the data fetching. It takes an array of dependencies, in this case [GET_API_NAME]
, to identify the query. Whenever the dependencies change, React Query will automatically re-fetch the data. The fetchApi
function we defined earlier is passed as the second argument.
The enabled
option is set to !!token
to control whether the query should be enabled based on the presence of the authentication token. If there is no token available, the query will not be executed.
The onError
option allows us to handle any errors that occur during the query. In this case, we simply log the error to the console, but you can customize the error handling as per your requirements.
The hook returns an object containing various values: isLoading
indicates whether the data is currently being fetched, isError
indicates if an error occurred, data
contains the fetched data, error
holds the error object if any, and refetch
is a function to manually trigger a data re-fetch.
Section 3: Setting up Axios and Authorization
To make API requests with authentication, we'll use Axios, a popular JavaScript library. Axios provides an easy-to-use API for sending HTTP requests and handling responses. Additionally, we'll configure Axios to include the authorization token in the request headers. Let's set it up.
First, install Axios and import the necessary dependencies:
jsxCopy codeimport axios from "axios";
import Cookies from "js-cookie";
import { getApiURL } from "./baseURL";
Next, create an instance of Axios using the axios.create
method:
const client = axios.create({
baseURL: getApiURL(),
});
The baseURL
is set using the getApiURL
function, which should return the URL of your API.
Now, let's define a function called setAuthorizationHeader
:
export const setAuthorizationHeader = () => {
const token = Cookies.get("token");
if (token) {
client.defaults.headers.common["Authorization"] = `Bearer ${token}`;
} else {
delete client.defaults.headers.common["Authorization"];
}
};
The setAuthorizationHeader
function retrieves the authentication token from cookies using Cookies.get
. If a token is available, it sets the Authorization
header in the Axios client to include the token. If there is no token, the Authorization
header is deleted.
To initialize the authorization header, call setAuthorizationHeader
:
codesetAuthorizationHeader();
Additionally, we can add an interceptor to update the authorization header before each request:
client.interceptors.request.use((config) => {
setAuthorizationHeader();
return config;
});
The interceptor calls setAuthorizationHeader
to ensure that the latest token is included in the request headers.
Finally, we can define a request
function to handle sending requests:
export const request = ({ ...options }) => {
const onSuccess = (response) => {
return response;
};
const onError = (error) => {
return error;
};
return client(options).then(onSuccess).catch(onError);
};
The request
function takes an options object and sends the request using the Axios client. It returns a promise that resolves with the response data on success or rejects with an error on failure.
Section 4: Usage
Now that we have our custom hook useUsers
set up, let's see how we can use it in a React component. We'll show an example of accessing the data
, isLoading
, and refetch
properties returned by the useApiQuery
hook.
const { data, isLoading, refetch } = useApiQuery();
If the data is available, we can map over the data
array and render a list item for each item in the data if it's an array.
Conclusion
In this blog post, we learned how to build a custom hook using React Query for data fetching and Axios for handling API requests and authentication. By combining these powerful libraries, we can create efficient and reusable code for managing API calls in our React applications.
Feel free to customize and expand upon the code snippets provided to fit your specific use case.
If you found this blog post helpful, feel free to follow me on Twitter @thedeepanshuweb, connect with me on LinkedIn Deepanshu Goel