I created a custom hook in my Nextjs application to send a request using Axios.
Here is my useApiRequest
file:
import { ErrorResponse, SuccessResponse } from "@/types/api";
import axios, { AxiosResponse } from "axios";
import { useState } from "react";
const useApiRequest = <T>(
httpMethod: string,
url: string,
data?: any
): [boolean, T | string, string] => {
const [response, setResponse] = useState<[boolean, T | string, string]>([
false,
"",
"",
]);
const fetchData = async () => {
try {
const apiResponse: AxiosResponse<SuccessResponse<T> | ErrorResponse> =
await axios({
method: httpMethod,
url: url,
data: data,
});
if ("result" in apiResponse.data && "message" in apiResponse.data) {
const successData: SuccessResponse<T> = apiResponse.data;
setResponse([true, successData.result, successData.message]);
} else {
const errorData: ErrorResponse = apiResponse.data;
setResponse([false, errorData.error, errorData.error]);
}
} catch (error) {
if (error instanceof Error) {
setResponse([false, "", error.message]);
} else {
setResponse([false, "", "Terjadi kesalahan"]);
}
}
};
fetchData();
return response;
};
export default useApiRequest;
I have used that hook in one of my pages like this:
import Button from "@/components/elements/buttons/Button";
import useApiRequest from "@/hooks/useApiRequest";
import Head from "next/head";
const JadwalPage = () => {
const handleLogin = () => {
const [isSuccess, responseData, message] = useApiRequest(
"post",
"/auth/login",
{
username: "admin",
password: "pratama-putra",
}
);
if (isSuccess) {
console.log("Data berhasil diperoleh:", responseData);
} else {
console.error("Gagal melakukan permintaan:", message);
}
};
return (
<div className="min-h-screen">
<Head>
<title>Jadwal Karyawan</title>
</Head>
<Button onClick={handleLogin}>Click me</Button>
</div>
);
};
export default JadwalPage;
Why do I always get an error Uncaught Error: Invalid hook call. Hooks can only be called inside of the body of a function component.
I tried to change useApiRequest
from an arrow function to a regular function, but it still produces the same error.
2
Answers
You need to use use Hooks at the top level of your React function. From the React documentation-
Only Call Hooks from React Functions
It’s not supported to call Hooks (functions starting with use) in any other cases, for example:
useEffect.
You should use your hook at the top level of your component. You can create behaviour like mutation. So whenever you call a hook it will return a function which can be further used to make API calls.
Use it like below: