I'm trying to do the following code but the linting is warning me to add the employeesApi to the dependency array in the useEffect. The problem is that it enters in an infinite loop and keeps executing the API request if I add the employeesApi to the dependency array
export const EmployeesListPage = () => {
const navigate = useNavigate();
const [employees, setEmployees] = useState<EmployeeListDto[]>([]);
const employeesApi = useApi(new EmployeesApi());
useEffect(() => {
async function getEmployeesList() {
const employeesList = await employeesApi.getEmployeesList();
setEmployees(employeesList);
}
getEmployeesList();
}, []);
return (...)
}
EDIT:
I found the solution using an article suggested by Bikas Lin
Turns out that I read some of the react articles as well and I found out that my custom hook would always be executed at every render.
and because of that, my useAPI was executed at every render and as a parameter, I was sending a new instance of my EmployeesApi at every render.
This makes the dependency array comparison crazy as react does a comparison with objects by its reference (different from a primitive value). So at every render the reference for the EmployeesApi would be a new one and that would trigger the useEffect.
I fixed by tweaking my useApi hook to use a STATE for the API and I'm now instantiating the API inside my custom hook like so:
export const useApi = <T extends IApi>(ApiType: new () => T): T => {
const { loggedUser } = useUserManagement();
const [api] = useState<T>(new ApiType());
api.setUser(loggedUser);
return api;
};
and now I can use it perfectly in my component because the reference will always be the same
export const EmployeesListPage = () => {
const navigate = useNavigate();
const [employees, setEmployees] = useState<EmployeeListDto[]>([]);
const employeesApi = useApi(EmployeesApi);
useEffect(() => {
async function getEmployeesList() {
const employeesList = await employeesApi.getEmployeesList();
setEmployees(employeesList);
}
getEmployeesList();
}, [employeesApi]);
return (...)
}