I'm trying to create a custom useFetch hook and it works in every component except one. In this one component it infinitely loops (but not so much that React stops it). This is the hook:
import { useState, useEffect, SetStateAction, Dispatch } from 'react';
import axios, { AxiosResponse } from 'axios';
const useFetch = (
method: 'POST' | 'GET',
url: string,
object?: any
): [
AxiosResponse,
'Loading' | 'Rendered' | 'Error',
Dispatch<SetStateAction<'Loading' | 'Rendered' | 'Error'>>
] => {
const [data, setData] = useState<AxiosResponse | null | void>(null);
const [compState, setCompState] = useState<'Loading' | 'Rendered' | 'Error'>('Loading');
useEffect(() => {
let isMounted = true;
setCompState('Loading');
if (method === 'GET') {
// ...
} else if (
method === 'POST' &&
object !== null &&
!Object.values(object).includes(null)
) {
axios
.post(url, object)
.then(res => {
if (isMounted) {
console.log(res.data);
setCompState('Rendered');
setData(res);
}
})
.catch(err => {
if (isMounted) {
console.log(err);
setCompState('Error');
setData(err);
}
});
} else return;
return () => {
isMounted = false;
};
}, [url, object]);
return [data as AxiosResponse, compState];
};
export default useFetch;
This is how I'm using it in the component:
const userId = localStorage.getItem('userId');
const [orders, compState] = useFetch('POST', '/orders', { userId });
I know part of what is causing the loop; it's because I have the object in the dependency array, and that if I remove it from the array, it stops looping. The problem is that I need the object in the array because, in this case, the object is just the userId, and I want the component to rerender when the user signs in on this page. I assume that something about the userId constant is the cause of this problem.
Before I extracted the custom hook, the constant was in the useEffect and this wasn't a problem, but I'm wondering if theirs a way to fix this that doesn't affect the reusability of the hook.